Vous êtes ici

PGPool : repliquer (master/master) et load balancer sur plusieurs instances postgresql

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 :

  •  2 ou 3 serveurs postgresql configuré comme tel :

- 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

  •  1 serveur ou nous allons mettre pgpool


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.

Tags: 

www.le-gas.fr : Le guide de l'admin Systeme