PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como obter alta disponibilidade do PostgreSQL com pgBouncer

No mundo do banco de dados, há muitos conceitos comuns, como alta disponibilidade, failover e pool de conexões. Todos eles são úteis para implementar em qualquer sistema, e até mesmo obrigatórios em alguns casos.

Um pool de conexões é um método de criar um pool de conexões e reutilizá-las evitando abrir novas conexões com o banco de dados o tempo todo, o que aumentará consideravelmente o desempenho de suas aplicações. O PgBouncer é um pool de conexões popular projetado para PostgreSQL, mas não é suficiente para atingir a Alta Disponibilidade do PostgreSQL por si só, pois não possui configuração de vários hosts, failover ou detecção.

Usar um Load Balancer é uma forma de ter Alta Disponibilidade em sua topologia de banco de dados. Pode ser útil para redirecionar o tráfego para nós de banco de dados íntegros, distribuir o tráfego entre vários servidores para melhorar o desempenho ou apenas para ter um único ponto de extremidade configurado em seu aplicativo para facilitar a configuração e o processo de failover. Para isso, o HAProxy é uma boa opção para complementar seu pool de conexões, pois é um proxy de código aberto que pode ser usado para implementar alta disponibilidade, balanceamento de carga e proxy para aplicativos baseados em TCP e HTTP.

Neste blog, usaremos os dois conceitos, balanceador de carga e pool de conexões (HAProxy + PgBouncer), para implantar um ambiente de alta disponibilidade para seu banco de dados PostgreSQL.

Como o PgBouncer funciona

O PgBouncer atua como um servidor PostgreSQL, então você só precisa acessar seu banco de dados usando as informações do PgBouncer (Endereço IP/Hostname e Porta), e o PgBouncer criará uma conexão com o servidor PostgreSQL, ou reutilize um se existir.

Quando o PgBouncer recebe uma conexão, ele realiza a autenticação, que depende do método especificado no arquivo de configuração. O PgBouncer suporta todos os mecanismos de autenticação que o servidor PostgreSQL suporta. Depois disso, o PgBouncer verifica se há uma conexão em cache, com a mesma combinação de nome de usuário + banco de dados. Se uma conexão em cache for encontrada, ele retorna a conexão ao cliente, caso contrário, cria uma nova conexão. Dependendo da configuração do PgBouncer e do número de conexões ativas, pode ser possível que a nova conexão seja enfileirada até que possa ser criada, ou mesmo abortada.

O comportamento do PgBouncer depende do modo de pool configurado:

  • pool de sessões (padrão):Quando um cliente se conecta, uma conexão de servidor será atribuída a ele durante todo o tempo em que o cliente permanecer conectado. Quando o cliente se desconectar, a conexão do servidor será colocada de volta no pool.
  • pool de transações :Uma conexão de servidor é atribuída a um cliente somente durante uma transação. Quando o PgBouncer perceber que a transação terminou, a conexão do servidor será colocada de volta no pool.
  • conjunto de instruções :A conexão do servidor será colocada de volta no pool imediatamente após a conclusão de uma consulta. As transações com vários extratos não são permitidas nesse modo, pois seriam interrompidas.

Para equilibrar as consultas entre vários servidores, no lado do PgBouncer, pode ser uma boa ideia diminuir o server_lifetime e também ativar o server_round_robin. Por padrão, as conexões inativas são reutilizadas pelo algoritmo LIFO, que pode não funcionar tão bem quando um balanceador de carga é usado.

Como instalar o PgBouncer

Vamos supor que você tenha o cluster PostgreSQL e o HAProxy implantados e ele esteja funcionando, caso contrário, você pode seguir esta postagem do blog para implantar facilmente o PostgreSQL para alta disponibilidade.

Você pode instalar o PgBouncer em cada nó do banco de dados ou em uma máquina externa, em qualquer caso, você terá algo assim:

Para obter o software PgBouncer, você pode ir para a seção de download do PgBouncer, ou use os repositórios RPM ou DEB. Para este exemplo, usaremos o CentOS 8 e o instalaremos a partir do repositório oficial do PostgreSQL.

Primeiro, baixe e instale o repositório correspondente do site PostgreSQL (caso ainda não o tenha 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

Em seguida, instale o pacote PgBouncer:

$ yum install pgbouncer

Verifique a instalação:

$ 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

Quando estiver concluído, você terá um novo arquivo de configuração localizado em /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

Vamos ver esses parâmetros um por um:

  • Seção de bancos de dados [bancos de dados]: Este contém pares chave=valor onde a chave será tomada como um nome de banco de dados e o valor como uma lista de estilo de string de conexão libpq de pares chave=valor.
  • Seção de usuário [usuários]: Este contém pares chave=valor onde a chave será tomada como um nome de usuário e o valor como uma lista de estilo de string de conexão libpq de pares chave=valor de definições de configuração específicas para este usuário.
  • arquivo de registro :especifica o arquivo de log. O arquivo de log é mantido aberto, portanto, após a rotação, mate -HUP ou no console RELOAD; deve ser feito.
  • pidfile :Especifica o arquivo PID. Sem o conjunto pidfile, o daemon não é permitido.
  • listen_addr :especifica uma lista de endereços onde escutar conexões TCP. Você também pode usar * significando “ouvir em todos os endereços”. Quando não definido, somente conexões de soquete Unix são aceitas.
  • listen_port: Em qual porta escutar. Aplica-se a soquetes TCP e Unix. A porta padrão é 6432.
  • auth_type: Como autenticar usuários.
  • auth_file :O nome do arquivo para carregar nomes de usuário e senhas.
  • admin_users :lista separada por vírgulas de usuários de banco de dados que têm permissão para conectar e executar todos os comandos no console.
  • stats_users :lista separada por vírgulas de usuários de banco de dados que têm permissão para se conectar e executar consultas somente leitura no console.

Esta é apenas uma amostra do arquivo de configuração padrão, pois o original tem 359 linhas, mas o restante das linhas é comentado por padrão. Para obter todos os parâmetros disponíveis, você pode verificar a documentação oficial.

Como usar o PgBouncer

Agora, vamos ver uma configuração básica para que funcione.

O arquivo de configuração 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

E o arquivo de autenticação:

$ cat /etc/pgbouncer/userlist.txt

"admindb" "root123"

Então, neste caso, instalei o PgBouncer no mesmo nó do banco de dados, escutando todos os endereços IP, e ele se conecta a um banco de dados PostgreSQL chamado “world”. Também estou gerenciando os usuários permitidos no arquivo userlist.txt com uma senha de texto simples que pode ser criptografada, se necessário.

Para iniciar o serviço PgBouncer, basta executar o seguinte comando:

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

Onde -d significa “daemon”, então ele será executado em 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 você pode ver, o PgBouncer está ativo e aguardando conexões na porta 6432. Para acessar o banco de dados PostgreSQL, execute o seguinte comando usando suas informações locais (porta, host, nome de usuário e nome do banco de dados) :

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

Password for user admindb:

psql (12.4)

Type "help" for help.



world=#

Lembre-se de que o nome do banco de dados (world) é o banco de dados configurado em seu arquivo de configuração do PgBouncer:

[databases]

world = host=127.0.0.1 port=5432 dbname=world

Monitorando e gerenciando o PgBouncer

Em vez de acessar seu banco de dados PostgreSQL, você pode se conectar diretamente ao PgBouncer para gerenciá-lo ou monitorá-lo. Para isso, use o mesmo comando que você usou anteriormente, mas altere o banco de dados para “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

Agora, você pode executar diferentes comandos do PgBouncer para monitorá-lo:

MOSTRAR 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)

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)

E para gerenciá-lo...

RECARREGAR:

pgbouncer=# RELOAD;

RELOAD

PAUSA:

pgbouncer=# PAUSE world;

PAUSE

RESUMO:

pgbouncer=# RESUME world;

RESUME

Esses comandos são apenas um exemplo. Para obter uma lista completa de comandos, consulte a documentação oficial.

Conclusão

Usar uma combinação de PgBouncer + HAProxy + PostgreSQL é uma boa maneira de obter alta disponibilidade para seu cluster PostgreSQL, melhorando o desempenho do banco de dados ao mesmo tempo.

Como você pode ver, se você tiver seu ambiente PostgreSQL instalado, que pode ser implantado usando o ClusterControl em apenas alguns cliques, poderá adicionar facilmente o PgBouncer para aproveitar a vantagem de ter um pool de conexões para seus sistemas.