Nous allons voir dans cet article comment faire un pool d'instances postgresql, ici 3 instances. Que fais donc pgpool2 :
- Fonctionnement de base, pool de connexion, c'est a dire que c'est lui qui gére les connections a votre ou vos bdd, même si la connexion n'est pas établi a votre postgresql, pgpool garde les connections ouverte vers ces clients et les repartis au besoin selon leurs activités/inactivités
- Replication en mode master master, c'est à dire qu'il écrit en même temps sur toutes les instances postgresql que vous lui avez configuré
- Load balancer : il reparti les requêtes de lecture entre tous les postgresql qui lui sont associés
Nous allons ici configurer pgpool pour qu'il replique sur 3 instances postgresql (donc 3 postgresql master ), il va également faire du lad balancine pour les lectures, et bien sur pool de connexion.
Prerequis :
- modification à apporter au fichier : /etc/postgresql/9.4/main/postgresql.conf :listen_addresses = '*'
- modification du fichier /etc/postgresql/9.4/main/pg_hba.conf pour trust l'ip du pgpool (il est également possible de faire une authentification par md5)host all all 192.168.0.254/32 trust
Installation et configuration de pgpool
1) Installer pgpool2, ici sur debian :
apt-get install pgpool2
2) Editer le fichier /etc/pgpool/pgpool.conf pour y insérer/modifier les lignes suivantes :# - Backend Connection Settings -
backend_hostname0 = 'marathon.le-gas.fr'
backend_port0 = 31199
backend_weight0 = 1
backend_flag0 = 'ALLOW_TO_FAILOVER'
backend_hostname1 = 'marathon.le-gas.fr'
backend_port1 = 31730
backend_weight1 = 1
backend_flag1 = 'ALLOW_TO_FAILOVER'
backend_hostname2 = 'marathon.le-gas.fr'
backend_port2 = 31649
backend_weight2 = 1
backend_flag2 = 'ALLOW_TO_FAILOVER'
# - Authentication -
enable_pool_hba = on
# Use pool_hba.conf for client authentication
pool_passwd = 'pool_passwd'
#------------------------------------------------------------------------------
# REPLICATION MODE
#------------------------------------------------------------------------------
replication_mode = on
#------------------------------------------------------------------------------
# LOAD BALANCING MODE
#------------------------------------------------------------------------------
load_balance_mode = on
explication :
backend_hostname0 = 'marathon.le-gas.fr' > adresse ou ip de ma première instance postgresql
backend_port0 = 31199 > port de ma première instance postgresql
backend_weight0 = 1 > poid de ma première instance, c'est ce qui va servir au load balancer pour la répartition des requêtes
backend_flag0 = 'ALLOW_TO_FAILOVER'
enable_pool_hba = on > autorise l'utilisation du fichier de conf pool_hba pour autoriser pgpool a gérer les accès
pool_passwd = 'pool_passwd' > Si vous ne voulez pas truster l'ip de votre pgpool pour son authentification au pres des instances postgresql, c'est ce fichier qui contiendra le hasch du mot de passe de connexion aux instances postgresql
replication_mode = on > ici on précise a pgpool que c'est lui qui gére la réplication entre les instances postgresql
load_balance_mode = on > on active le load balancer
3) Editier le fichier /etc/pgpool2/pool_hba.conf, c'est l'équivalent du pg_hba.conf des instances postgresql# TYPE DATABASE USER CIDR-ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
host all all 192.168.0.0/24 md5
ici, c'est la même chose que pour le pg_hba.conf des instances postgresql.
4) Editier le fichier pcp.conf pour y mettre le user et pass d'admin pcp (qui permet de gérer les noeuds)
exemple :
pg_md5 pass (pg_md5 permet de générer un mot de passe postgresql)
1a1dc91c907325c69271ddf0c944bc72
donc vi pcp.conf :postgres:1a1dc91c907325c69271ddf0c944bc72
5) executer pgpool : pgpool -n -d > /tmp/pgpool.log 2>&1 &
, l'idéal sera d'en faire un service pour de la prod.
6) Verifier le bon fonctionnement de pgpool, pour cela on s'y connect selon ce que vous avez paramétré dans le hba, ici j'ai trust l'utilisateur postgres donc :su postgres -c 'psql'
Puis, nous vérifions le status de pgpool :show pool_status ;
backend_hostname0 | marathon.le-gas.fr | backend #0 hostname
backend_port0 | 31199 | backend #0 port number
backend_weight0 | 0.333333 | weight of backend #0
backend_data_directory0 | | data directory for backend #0
backend_status0 | 2 | status of backend #0
standby_delay0 | 0 | standby delay of backend #0
backend_flag0 | ALLOW_TO_FAILOVER | backend #0 flag
backend_hostname1 | marathon.le-gas.fr | backend #1 hostname
backend_port1 | 31730 | backend #1 port number
backend_weight1 | 0.333333 | weight of backend #1
backend_data_directory1 | | data directory for backend #1
backend_status1 | 2 | status of backend #1
standby_delay1 | 0 | standby delay of backend #1
backend_flag1 | ALLOW_TO_FAILOVER | backend #1 flag
backend_hostname2 | marathon.le-gas.fr | backend #2 hostname
backend_port2 | 31649 | backend #2 port number
backend_weight2 | 0.333333 | weight of backend #2
backend_data_directory2 | | data directory for backend #2
backend_status2 | 2 | status of backend #2
standby_delay2 | 0 | standby delay of backend #2
backend_flag2 | ALLOW_TO_FAILOVER | backend #2 flag
heartbeat_device0 | | name of NIC device #0 for sending hearbeat
heartbeat_destination0 | host0_ip1 | destination host for sending heartbeat using
NIC device 0
heartbeat_destination_port0 | 9694 | destination port for sending heartbeat using
NIC device 0
Ici nous pouvons voir le status de nos instances postgresql : backend_status2 | 2
Precisions sur les différent status possible (ici 2) :
0 - Cet état est uniquement utilisé pendant l'initialisation. PCP ne l'affichera jamais
1 - Le nœud est en ligne, mais aucune connexion n'est encore faite dessus
2 - Le nœud est en ligne, et les connexions sont poolés
3 - Le nœud est arrêté
7) Quittons le client pg, et voyons comment administrer les noeuds avec pcp :
Detacher un noeud :pcp_detach_node 5 localhost 9898 postgres pass 0
Attacher un noeud :pcp_attach_node 5 localhost 9898 postgres pass 0
Explication des commandes :
pcp_detach_node ou pcp_attach_node > permet d'attacher ou détacher une instance postgresql du pool
5 > timeout de la commande
localhost > adresse du serveur pgpool
9898 > port d'administration du pgpool
postgres > utilisateur admin déclaré dans le pcp.conf
pass > password admin declare dans le pcp.cnf
0 > numéro de l'instance sur laquelle agir
8) Cas concret :
- Peut on exécuter plusieurs select en // :
oui, chaque select sera dispatché sur les différentes machines pg présente dans le pool
- Les tables pg_stat sont elle correctement alimentées depuis pg_pool :
Oui, si vous exécutez plusieurs requêtes qui sont dispatchées sur plusieurs pg depuis pgpool, vos tables pg_stat prendrons en compte toutes ces requêtes et pas uniquement les requêtes executées sur le pg sur lequel le pgpool vous a connecté
- Peut il y avoir une incohérence de données si plusieurs requêtes d'écritures passent en même temps que les selects :
Non, pgpool attend l'acquittement de tous les pg de son pool pour rentre la main, donc pas d'incohérence de données, par contre la multiplication du nombre d'instance pg au sein du pool peut avoir des conséquences sur la performance en écriture
Voila, vous avez maintenant toutes les informations nécessaires pour mettre en place un pool d'instances postgresql. Nous allons voir dans un prochain article, comment réparer une instance qui a été sortie du pool, voir comment en ajouter une en cours de route, et surtout voir comment lancer un recovery automatique d'un instance depuis pgpool.