sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo lograr una alta disponibilidad de PostgreSQL con pgBouncer

En el mundo de las bases de datos, hay muchos conceptos comunes como alta disponibilidad, conmutación por error y agrupación de conexiones. Todas ellas son cosas útiles para implementar en cualquier sistema, e incluso imprescindibles en algunos casos.

Una agrupación de conexiones es un método para crear un conjunto de conexiones y reutilizarlas evitando abrir nuevas conexiones a la base de datos todo el tiempo, lo que aumentará considerablemente el rendimiento de sus aplicaciones. PgBouncer es un agrupador de conexiones popular diseñado para PostgreSQL, pero no es suficiente para lograr la alta disponibilidad de PostgreSQL por sí solo, ya que no tiene configuración de múltiples hosts, conmutación por error ni detección.

Usar un Load Balancer es una forma de tener alta disponibilidad en la topología de su base de datos. Podría ser útil para redirigir el tráfico a nodos de bases de datos en buen estado, distribuir el tráfico entre varios servidores para mejorar el rendimiento o simplemente tener un punto final único configurado en su aplicación para una configuración más sencilla y un proceso de conmutación por error. Para esto, HAProxy es una buena opción para complementar su agrupador de conexiones, ya que es un proxy de código abierto que se puede usar para implementar alta disponibilidad, equilibrio de carga y proxy para aplicaciones basadas en TCP y HTTP.

En este blog, utilizaremos ambos conceptos, Load Balancer y Connection pooling (HAProxy + PgBouncer), para implementar un entorno de alta disponibilidad para su base de datos PostgreSQL.

Cómo funciona PgBouncer

PgBouncer actúa como un servidor PostgreSQL, por lo que solo necesita acceder a su base de datos utilizando la información de PgBouncer (dirección IP/nombre de host y puerto), y PgBouncer creará una conexión con el servidor PostgreSQL, o reutilice uno si existe.

Cuando PgBouncer recibe una conexión, realiza la autenticación, que depende del método especificado en el archivo de configuración. PgBouncer admite todos los mecanismos de autenticación que admite el servidor PostgreSQL. Después de esto, PgBouncer busca una conexión en caché, con la misma combinación de nombre de usuario y base de datos. Si se encuentra una conexión en caché, devuelve la conexión al cliente, si no, crea una nueva conexión. Según la configuración de PgBouncer y la cantidad de conexiones activas, es posible que la nueva conexión se ponga en cola hasta que se pueda crear o incluso cancelar.

El comportamiento de PgBouncer depende del modo de agrupación configurado:

  • agrupación de sesiones (predeterminado):cuando un cliente se conecta, se le asignará una conexión de servidor durante todo el tiempo que el cliente permanezca conectado. Cuando el cliente se desconecte, la conexión del servidor se volverá a colocar en el grupo.
  • agrupación de transacciones :Una conexión de servidor se asigna a un cliente solo durante una transacción. Cuando PgBouncer se dé cuenta de que la transacción ha terminado, la conexión del servidor se volverá a colocar en el grupo.
  • combinación de sentencias :la conexión del servidor se volverá a colocar en el grupo inmediatamente después de que se complete una consulta. Las transacciones de estados de cuenta múltiples no están permitidas en este modo porque se romperían.

Para equilibrar las consultas entre varios servidores, en el lado de PgBouncer, puede ser una buena idea hacer que server_lifetime sea más pequeño y también activar server_round_robin. De forma predeterminada, el algoritmo LIFO reutiliza las conexiones inactivas, lo que puede no funcionar tan bien cuando se utiliza un equilibrador de carga.

Cómo instalar PgBouncer

Supondremos que tiene implementado su clúster de PostgreSQL y HAProxy, y que está en funcionamiento; de lo contrario, puede seguir esta publicación de blog para implementar fácilmente PostgreSQL para alta disponibilidad.

Puede instalar PgBouncer en cada nodo de la base de datos o en una máquina externa, en cualquier caso, tendrá algo como esto:

Para obtener el software PgBouncer puede ir a la sección de descargas de PgBouncer, o utilice los repositorios RPM o DEB. Para este ejemplo, usaremos CentOS 8 y lo instalaremos desde el repositorio oficial de PostgreSQL.

Primero, descargue e instale el repositorio correspondiente del sitio de PostgreSQL (si aún no lo tiene instalado):

$ 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

Luego, instale el paquete PgBouncer:

$ yum install pgbouncer

Verificar la instalación:

$ 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

Cuando se complete, tendrá un nuevo archivo de configuración ubicado en /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

Veamos estos parámetros uno por uno:

  • Sección de bases de datos [bases de datos]: Esto contiene pares clave=valor donde la clave se tomará como un nombre de base de datos y el valor como una lista de pares clave=valor al estilo de cadena de conexión libpq.
  • Sección de usuario [usuarios]: Esto contiene pares clave=valor donde la clave se tomará como un nombre de usuario y el valor como una lista de estilo de cadena de conexión libpq de pares clave=valor de ajustes de configuración específicos para este usuario.
  • archivo de registro :especifica el archivo de registro. El archivo de registro se mantiene abierto, así que después de la rotación matar -HUP o en la consola RECARGAR; debe hacerse.
  • pidfile :especifica el archivo PID. Sin el conjunto pidfile, el daemon no está permitido.
  • dirección_de_escucha :Especifica una lista de direcciones donde escuchar conexiones TCP. También puede usar * que significa "escuchar en todas las direcciones". Cuando no se establece, solo se aceptan conexiones de socket Unix.
  • puerto de escucha: En qué puerto escuchar. Se aplica a los sockets TCP y Unix. El puerto predeterminado es 6432.
  • auth_type: Cómo autenticar usuarios.
  • archivo_autenticación :El nombre del archivo desde el que cargar nombres de usuario y contraseñas.
  • usuarios_administradores :lista separada por comas de los usuarios de la base de datos que pueden conectarse y ejecutar todos los comandos en la consola.
  • estadísticas_usuarios :lista separada por comas de los usuarios de la base de datos que pueden conectarse y ejecutar consultas de solo lectura en la consola.

Esta es solo una muestra del archivo de configuración predeterminado, ya que el original tiene 359 líneas, pero el resto de las líneas están comentadas de forma predeterminada. Para obtener todos los parámetros disponibles, puede consultar la documentación oficial.

Cómo usar PgBouncer

Ahora, veamos una configuración básica para que funcione.

El archivo de configuración 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

Y el archivo de autenticación:

$ cat /etc/pgbouncer/userlist.txt

"admindb" "root123"

Entonces, en este caso, instalé PgBouncer en el mismo nodo de la base de datos, escuchando todas las direcciones IP, y se conecta a una base de datos PostgreSQL llamada "mundo". También administro los usuarios permitidos en el archivo userlist.txt con una contraseña de texto sin formato que se puede cifrar si es necesario.

Para iniciar el servicio PgBouncer, solo necesita ejecutar el siguiente comando:

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

Donde -d significa "demonio", por lo que se ejecutará en segundo plano.

$ 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

Como puede ver, PgBouncer está activo y esperando conexiones en el puerto 6432. Para acceder a la base de datos PostgreSQL, ejecute el siguiente comando usando su información local (puerto, host, nombre de usuario y nombre de la base de datos) :

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

Password for user admindb:

psql (12.4)

Type "help" for help.



world=#

Recuerde que el nombre de la base de datos (mundo) es la base de datos configurada en su archivo de configuración de PgBouncer:

[databases]

world = host=127.0.0.1 port=5432 dbname=world

Supervisión y administración de PgBouncer

En lugar de acceder a su base de datos PostgreSQL, puede conectarse directamente a PgBouncer para administrarla o monitorearla. Para esto, usa el mismo comando que usaste anteriormente, pero cambia la base de datos a “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

Ahora, puede ejecutar diferentes comandos de PgBouncer para monitorearlo:

MOSTRAR ESTADÍSTICAS_TOTALES:

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)

MOSTRAR SERVIDORES:

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)

MOSTRAR CLIENTES:

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)

MOSTRAR PISCINAS:

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)

Y gestionarlo...

VOLVER A CARGAR:

pgbouncer=# RELOAD;

RELOAD

PAUSA:

pgbouncer=# PAUSE world;

PAUSE

REANUDAR:

pgbouncer=# RESUME world;

RESUME

Esos comandos son solo un ejemplo. Para obtener una lista completa de comandos, consulte la documentación oficial.

Conclusión

Usar una combinación de PgBouncer + HAProxy + PostgreSQL es una buena forma de lograr alta disponibilidad para su clúster de PostgreSQL mejorando al mismo tiempo el rendimiento de su base de datos.

Como puede ver, si tiene instalado su entorno PostgreSQL, que puede implementar usando ClusterControl con solo unos pocos clics, puede agregar fácilmente PgBouncer para aprovechar las ventajas de tener un agrupador de conexiones para sus sistemas.