PgBouncer: Pool de Conexões

PgBouncer: Pool de Conexões

O PgBouncer se define como um “pool de conexões leve para PostgreSQL” (site do projeto aqui).

Seu primeiro release púbico, a versão 1.0, ocorreu em Março de 2007. Atualmente ele possui versões para Windows e Linux (código-fonte e instruções para instalação aqui).

A principal função do PgBouncer é ser um pool de conexões.

O conceito geral é bastante simples: os clientes (usuários e sistemas) apontam suas connection strings para o IP/Porta do PgBouncer, usando um usuário especificamente criado para esta conexão (que pode ou não ser o mesmo do banco de dados), eles são introduzidos em uma fila e esta fila é executada pelo banco de dados através de uma conexão entre o pool e o banco de dados.

Até aqui nenhuma novidade, afinal, esta é a forma como o sistema se conectaria ao banco de dados de maneira geral. Os benefícios desta arquitetura começam com os parâmetros de gerenciamento de conexões oferecidos pelo PgBouncer, dentre eles:

Pool_Mode: Define o modo pelo qual as instruções enviadas pelos clientes são processadas pelo banco de dados. Existem 3 modos:

Session: A conexão entre o pool e o banco de dados só é encerrada quando a sessão do usuário desconecta, é o valor padrão e é o comportamento normal em um banco de dados sem pool de conexões.

Transaction: A conexão é encerrada com o fim de uma transação. É importante lembrar que a conexão entre o cliente final e o pool se mantém, dando a ilusão de conexão ativa, mas o pool, para este cliente em específico, não estará mais conectado ao banco de dados até que uma nova transação se inicie e comece a ser executada. Este comportamento nos ajuda a não manter no banco de dados conexões abertas sem necessidade, visto que cada conexão utiliza recursos que, se não estiverem em uso, poderiam ser melhor utilizados por outras sessões ativas.

Statement: A conexão entre o pool e o banco de dados se encerra após a execução de um statement, ou seja, de um comando qualquer. Este tipo de configuração acaba impedindo a execução de transações, esta opção é recomendada com cautela.

Max_Client_Conn: Define o número máximo de pessoas que podem se conectar ao pool de conexões. Não confundir com a quantidade de conexões efetivamente abertas entre o pool e o banco de dados.

Default_Pool_Size: O tamanho padrão do pool para cada combinação usuário/banco de dados. Pode ser sobrescrita na configuração individual do banco de dados. Este é o valor máximo de conexões que serão abertas pelo pool para executar queries no banco de dados, dentro do modo de pool escolhido em Pool_Mode.

Min_Pool_Size: Este é um parâmetro interessante. Como abrir uma conexão com o banco de dados pode ser algo custoso, você pode definir um mínimo de conexões abertas entre o pool e o banco de dados, e estas ficaram abertas, mesmo que em idle, para que quando uma nova solicitação de execução de query chegar, o pool não tenha o overhead de ter que abrir a conexão.

Server_Check_Delay: O tempo em que uma conexão entre o pool e o banco de dados permanecerá aberta após o fim da execução das queries. Assim como a configuração anterior, esta configuração tenta ajudar a evitar o overhead de criação/destruição de conexões com o banco de dados.

Server_Lifetime: Tempo máximo de uma conexão entre o pool e o banco de dados. Cuidado com esta configuração, este time-out funciona até para conexões ativas. Para matar apenas conexões idle, veja a configuração abaixo.

Server_Idle_Timeout: Tempo máximo em que uma conexão idle será mantida entre o pool e o banco de dados.

Client_Idle_Timeout: Desta vez estamos falando da conexão entre o cliente/usuário e o pool de conexões. As conexões com mais do que este tempo em estado idle serão mortas.

Idle_Transcation_Timeout: O mesmo que o parâmetro anterior, porém para conexões no estado “Idle in Transaction”.

Estas são algumas das configurações disponíveis no PgBouncer e que tornam a conexão através do pool melhor gerenciável do que as feitas diretamente entre o cliente e o banco de dados.


Outro ponto importante é a Segurança. Você pode criar um usuário específico para que todos os clientes possam se autenticar no banco de dados, porém, este usuário não precisa ter nenhum privilégio no banco de dados. Desta forma, você pode distribuir este usuário/senha para seus clientes internos e externos e estes apenas poderão se conectar ao banco de dados através do pool de conexões, com todas as regras aplicadas. Outro ponto importante é que a conexão entre o pool e o banco de dados é feita por uma connection string interna, escondendo do usuário final o usuário que realmente está se conectando à base de dados. Desta forma ele  não terá acesso a esta informação.


Este recurso é particularmente importante pois, infelizmente, muitos clientes distribuem a senha do super usuário Postgres para todos os sistemas e clientes internos, dando acessos desnecessários à todo o cluster, ao inveś de fechar os privilégios por banco de dados. Através desta técnica do PgBouncer, você pode alterar os usuários e privilégios da conexão com o banco de dados sem ter que informar seus clientes finais, que continuarão usando o usuário de conexão ao pool.


Por fim, mas não menos importante, é a habilidade do pool em realizar o failover de um cluster de banco de dados. O PostgreSQL nos dá, nativamente, a capacidade de replicar o banco de dados principal para um ou mais bancos de dados secundários, que podem ficar disponíveis apenas para leitura. No caso de falha do servidor primário, o servidor secundário pode ser promovido a primário e continuar a servir os sistemas e clientes.
Em uma conexão direta ao banco de dados, os sistemas e clientes teriam que refazer a connection string, ou a equipe de infraestrutura teria que ter a capacidade de alterar o DNS/IP das máquinas, fazendo com que os clientes acessem o secundário através do IP que antes pertencia ao primário. Esta técnica é muito utilizado e possui um downtime relativamente baixo, provavelmente de alguns minutos dependendo das condições e equipes envolvidas.


Com o PgBouncer, basta alterar a configuração interna para que a connection string  do antigo secundário seja agora a do primário. Esta alteração requer um reload da configuração e o processo todo pode ser realizado em alguns segundos, sem que os usuários tenham que se reconectar à base de dados. Obviamente, aqueles usuários que estavam executando uma transação no momento da queda, perceberão a queda, porém os que estavam apenas conectados, estavam apenas conectados ao pool e desta forma, ao enviar uma nova query, ela será direcionada para o novo primário, sem que o cliente final perceba o failover.
Todo este processo diminui drasticamente o downtime do serviço, aumentando o SLA como um todo.


Com isso, indicamos o uso do PgBouncer em seu ambiente para que você possa usufruir de todos estes benefícios!

Veja uma palestra completa sobre o assunto em: https://www.infoq.com/br/presentations/pgbouncer-pool-seguranca-e-disaster

pereira

Comments are closed.