PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment atteindre la haute disponibilité de PostgreSQL avec pgBouncer

Dans le monde des bases de données, il existe de nombreux concepts communs tels que la haute disponibilité, le basculement et le regroupement de connexions. Toutes sont des choses utiles à mettre en œuvre sur n'importe quel système, et même indispensables dans certains cas.

Un regroupement de connexions est une méthode permettant de créer un pool de connexions et de les réutiliser en évitant d'ouvrir constamment de nouvelles connexions à la base de données, ce qui augmentera considérablement les performances de vos applications. PgBouncer est un pooleur de connexions populaire conçu pour PostgreSQL, mais il ne suffit pas à lui seul d'atteindre la haute disponibilité de PostgreSQL car il n'a pas de configuration multi-hôte, de basculement ou de détection.

L'utilisation d'un équilibreur de charge est un moyen d'avoir une haute disponibilité dans la topologie de votre base de données. Cela peut être utile pour rediriger le trafic vers des nœuds de base de données sains, répartir le trafic sur plusieurs serveurs pour améliorer les performances ou simplement pour avoir un seul point de terminaison configuré dans votre application pour une configuration et un processus de basculement plus faciles. Pour cela, HAProxy est une bonne option pour compléter votre pooler de connexions, car il s'agit d'un proxy open source qui peut être utilisé pour mettre en œuvre la haute disponibilité, l'équilibrage de charge et le proxy pour les applications basées sur TCP et HTTP.

Dans ce blog, nous utiliserons les deux concepts, Load Balancer et Connection pooling (HAProxy + PgBouncer), pour déployer un environnement Haute Disponibilité pour votre base de données PostgreSQL.

Comment fonctionne PgBouncer

PgBouncer agit comme un serveur PostgreSQL, il vous suffit donc d'accéder à votre base de données en utilisant les informations PgBouncer (adresse IP/nom d'hôte et port), et PgBouncer créera une connexion au serveur PostgreSQL, ou il réutilisez-en un s'il existe.

Lorsque PgBouncer reçoit une connexion, il effectue l'authentification, qui dépend de la méthode spécifiée dans le fichier de configuration. PgBouncer prend en charge tous les mécanismes d'authentification pris en charge par le serveur PostgreSQL. Après cela, PgBouncer recherche une connexion en cache, avec la même combinaison nom d'utilisateur + base de données. Si une connexion en cache est trouvée, il renvoie la connexion au client, sinon, il crée une nouvelle connexion. En fonction de la configuration de PgBouncer et du nombre de connexions actives, il est possible que la nouvelle connexion soit mise en file d'attente jusqu'à ce qu'elle puisse être créée, voire abandonnée.

Le comportement de PgBouncer dépend du mode de regroupement configuré :

  • regroupement de sessions (par défaut) :lorsqu'un client se connecte, une connexion au serveur lui est attribuée pendant toute la durée pendant laquelle le client reste connecté. Lorsque le client se déconnecte, la connexion au serveur est remise dans le pool.
  • regroupement des transactions :Une connexion serveur est attribuée à un client uniquement lors d'une transaction. Lorsque PgBouncer remarque que la transaction est terminée, la connexion au serveur sera remise dans le pool.
  • regroupement d'instructions :La connexion au serveur sera remise dans le pool immédiatement après la fin d'une requête. Les transactions multi-relevés ne sont pas autorisées dans ce mode car elles ne fonctionneraient pas.

Pour équilibrer les requêtes entre plusieurs serveurs, du côté de PgBouncer, il peut être judicieux de réduire la taille de server_lifetime et d'activer également server_round_robin. Par défaut, les connexions inactives sont réutilisées par l'algorithme LIFO, qui peut ne pas fonctionner aussi bien lorsqu'un équilibreur de charge est utilisé.

Comment installer PgBouncer

Nous supposerons que vous avez déployé votre cluster PostgreSQL et HAProxy, et qu'il est opérationnel, sinon, vous pouvez suivre ce billet de blog pour déployer facilement PostgreSQL pour la haute disponibilité.

Vous pouvez installer PgBouncer sur chaque nœud de base de données ou sur une machine externe, dans tous les cas, vous aurez quelque chose comme ceci :

Pour obtenir le logiciel PgBouncer, vous pouvez vous rendre dans la section de téléchargement de PgBouncer, ou utilisez les référentiels RPM ou DEB. Pour cet exemple, nous utiliserons CentOS 8 et l'installerons à partir du référentiel officiel PostgreSQL.

Tout d'abord, téléchargez et installez le dépôt correspondant depuis le site PostgreSQL (si vous ne l'avez pas encore en place) :

$ wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm

$ rpm -Uvh pgdg-redhat-repo-latest.noarch.rpm

Ensuite, installez le package PgBouncer :

$ yum install pgbouncer

Vérifier l'installation :

$ pgbouncer --version

PgBouncer 1.14.0

libevent 2.1.8-stable

adns: c-ares 1.13.0

tls: OpenSSL 1.1.1c FIPS  28 May 2019

Une fois terminé, vous aurez un nouveau fichier de configuration situé dans /etc/pgbouncer/pgbouncer.ini :

[databases]

[users]

[pgbouncer]

logfile = /var/log/pgbouncer/pgbouncer.log

pidfile = /var/run/pgbouncer/pgbouncer.pid

listen_addr = 127.0.0.1

listen_port = 6432

auth_type = trust

auth_file = /etc/pgbouncer/userlist.txt

admin_users = postgres

stats_users = stats, postgres

Voyons ces paramètres un par un :

  • Section Bases de données [databases] : Celui-ci contient des paires clé=valeur où la clé sera considérée comme un nom de base de données et la valeur comme une liste de style de chaîne de connexion libpq de paires clé=valeur.
  • Section utilisateur [utilisateurs] : Celui-ci contient des paires clé=valeur où la clé sera considérée comme un nom d'utilisateur et la valeur comme une liste de style de chaîne de connexion libpq de paires clé=valeur de paramètres de configuration spécifiques à cet utilisateur.
  • fichier journal :Spécifie le fichier journal. Le fichier journal est maintenu ouvert, donc après la rotation kill -HUP ou sur console RELOAD; devrait être fait.
  • pidfile :Spécifie le fichier PID. Sans l'ensemble pidfile, le démon n'est pas autorisé.
  • listen_addr :spécifie une liste d'adresses où écouter les connexions TCP. Vous pouvez également utiliser * signifiant "écouter sur toutes les adresses". Lorsqu'il n'est pas défini, seules les connexions socket Unix sont acceptées.
  • port_écoute : Sur quel port écouter. S'applique aux sockets TCP et Unix. Le port par défaut est 6432.
  • auth_type : Comment authentifier les utilisateurs.
  • auth_file :Le nom du fichier à partir duquel charger les noms d'utilisateur et les mots de passe.
  • admin_users  :liste séparée par des virgules des utilisateurs de la base de données autorisés à se connecter et à exécuter toutes les commandes sur la console.
  • stats_users  :liste séparée par des virgules des utilisateurs de la base de données autorisés à se connecter et à exécuter des requêtes en lecture seule sur la console.

Ceci n'est qu'un exemple du fichier de configuration par défaut, car l'original a 359 lignes, mais le reste des lignes est commenté par défaut. Pour obtenir tous les paramètres disponibles, vous pouvez consulter la documentation officielle.

Comment utiliser PgBouncer

Maintenant, voyons une configuration de base pour le faire fonctionner.

Le fichier de configuration pgbouncer.ini :

$ cat /etc/pgbouncer/pgbouncer.ini

[databases]

world = host=127.0.0.1 port=5432 dbname=world

[pgbouncer]

logfile = /var/log/pgbouncer/pgbouncer.log

pidfile = /var/run/pgbouncer/pgbouncer.pid

listen_addr = *

listen_port = 6432

auth_type = md5

auth_file = /etc/pgbouncer/userlist.txt

admin_users = admindb

Et le fichier d'authentification :

$ cat /etc/pgbouncer/userlist.txt

"admindb" "root123"

Donc, dans ce cas, j'ai installé PgBouncer dans le même nœud de base de données, en écoutant toutes les adresses IP, et il se connecte à une base de données PostgreSQL appelée "world". Je gère également les utilisateurs autorisés dans le fichier userlist.txt avec un mot de passe en texte brut qui peut être chiffré si nécessaire.

Pour démarrer le service PgBouncer, il vous suffit d'exécuter la commande suivante :

$ pgbouncer -d /etc/pgbouncer/pgbouncer.ini

Où -d signifie "démon", donc il s'exécutera en arrière-plan.

$ netstat -pltn

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 0.0.0.0:6432            0.0.0.0:*               LISTEN      4274/pgbouncer

tcp6       0      0 :::6432                 :::*                    LISTEN      4274/pgbouncer

Comme vous pouvez le voir, PgBouncer est opérationnel et attend des connexions sur le port 6432. Pour accéder à la base de données PostgreSQL, exécutez la commande suivante en utilisant vos informations locales (port, hôte, nom d'utilisateur et nom de la base de données) :

$ psql -p 6432 -h 127.0.0.1 -U admindb world

Password for user admindb:

psql (12.4)

Type "help" for help.



world=#

Gardez à l'esprit que le nom de la base de données (world) est la base de données configurée dans votre fichier de configuration PgBouncer :

[databases]

world = host=127.0.0.1 port=5432 dbname=world

Surveillance et gestion de PgBouncer

Au lieu d'accéder à votre base de données PostgreSQL, vous pouvez vous connecter directement à PgBouncer pour la gérer ou la surveiller. Pour cela, utilisez la même commande que vous avez utilisée précédemment, mais changez la base de données en "pgbouncer":

$ psql -p 6432 -h 127.0.0.1 -U admindb pgbouncer

Password for user admindb:

psql (12.4, server 1.14.0/bouncer)

Type "help" for help.



pgbouncer=# SHOW HELP;

NOTICE:  Console usage

DETAIL:

SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION

SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM

SHOW DNS_HOSTS|DNS_ZONES

SHOW STATS|STATS_TOTALS|STATS_AVERAGES|TOTALS

SET key = arg

RELOAD

PAUSE [<db>]

RESUME [<db>]

DISABLE <db>

ENABLE <db>

RECONNECT [<db>]

KILL <db>

SUSPEND

SHUTDOWN



SHOW

Maintenant, vous pouvez exécuter différentes commandes PgBouncer pour le surveiller :

AFFICHER STATS_TOTALS :

pgbouncer=# SHOW STATS_TOTALS;

 database  | xact_count | query_count | bytes_received | bytes_sent | xact_time | query_time | wait_time

-----------+------------+-------------+----------------+------------+-----------+------------+-----------

 pgbouncer |          1 |           1 |              0 |          0 |         0 |          0 |         0

 world     |          2 |           2 |             59 |     234205 |      8351 |       8351 |      4828

(2 rows)

AFFICHER LES SERVEURS :

pgbouncer=# SHOW SERVERS;

 type |  user   | database | state  |   addr    | port | local_addr | local_port |      connect_time       |      request_time

| wait | wait_us | close_needed |      ptr       |      link      | remote_pid | tls

------+---------+----------+--------+-----------+------+------------+------------+-------------------------+-------------------------

+------+---------+--------------+----------------+----------------+------------+-----

 S    | admindb | world    | active | 127.0.0.1 | 5432 | 127.0.0.1  |      45052 | 2020-09-09 18:31:57 UTC | 2020-09-09 18:32:04 UTC

|    0 |       0 |            0 | 0x55b04a51b3d0 | 0x55b04a514810 |       5738 |

(1 row)

AFFICHER LES CLIENTS :

pgbouncer=# SHOW CLIENTS;

 type |  user   | database  | state  |   addr    | port  | local_addr | local_port |      connect_time       |      request_time

  | wait | wait_us | close_needed |      ptr       |      link      | remote_pid | tls

------+---------+-----------+--------+-----------+-------+------------+------------+-------------------------+-----------------------

--+------+---------+--------------+----------------+----------------+------------+-----

 C    | admindb | pgbouncer | active | 127.0.0.1 | 46950 | 127.0.0.1  |       6432 | 2020-09-09 18:29:46 UTC | 2020-09-09 18:55:11 UT

C | 1441 |  855140 |            0 | 0x55b04a5145e0 |                |          0 |

 C    | admindb | world     | active | 127.0.0.1 | 47710 | 127.0.0.1  |       6432 | 2020-09-09 18:31:41 UTC | 2020-09-09 18:32:04 UT

C |    0 |       0 |            0 | 0x55b04a514810 | 0x55b04a51b3d0 |          0 |

(2 rows)

AFFICHER LES PISCINES :

pgbouncer=# SHOW POOLS;

 database  |   user    | cl_active | cl_waiting | sv_active | sv_idle | sv_used | sv_tested | sv_login | maxwait | maxwait_us | pool_

mode

-----------+-----------+-----------+------------+-----------+---------+---------+-----------+----------+---------+------------+------

-----

 pgbouncer | pgbouncer |         1 |          0 |         0 |       0 |       0 |         0 |        0 |       0 |          0 | state

ment

 world     | admindb   |         1 |          0 |         1 |       0 |       0 |         0 |        0 |       0 |          0 | sessi

on

(2 rows)

Et pour le gérer...

RECHARGER :

pgbouncer=# RELOAD;

RELOAD

PAUSE :

pgbouncer=# PAUSE world;

PAUSE

REPRENDRE :

pgbouncer=# RESUME world;

RESUME

Ces commandes ne sont qu'un exemple. Pour une liste complète des commandes, veuillez vous référer à la documentation officielle.

Conclusion

L'utilisation d'une combinaison de PgBouncer + HAProxy + PostgreSQL est un bon moyen d'obtenir une haute disponibilité pour votre cluster PostgreSQL, améliorant en même temps les performances de votre base de données.

Comme vous pouvez le voir, si vous avez votre environnement PostgreSQL en place, que vous pouvez déployer à l'aide de ClusterControl en quelques clics, vous pouvez facilement ajouter PgBouncer pour profiter d'un pool de connexions pour vos systèmes.