FNSP Web Page

Connection pooling: porque é que a base cai sem ter tido um pico

Uma ligação ao Postgres não é um objeto: é um processo do lado do servidor, com a sua memória. Daí o preço, e daí a conta que quase ninguém faz antes de a base começar a recusar trabalho.

E o erro não aparece onde se espera. A base não fica lenta — fica a dizer que já tem clientes suficientes, enquanto o gráfico de carga dela está no chão.

1. Duzentos utilizadores não são duzentas ligações

Um pedido que corre uma consulta de 5 ms ocupa a ligação durante 5 ms. Em cem pedidos por segundo, meia ligação está ocupada em permanência. É por isso que um pool de dez aguenta um tráfego que parece exigir centenas: as ligações são reutilizadas, e o que varia é quanto tempo cada pedido as retém.

A consequência é que o número que importa não é «quantos utilizadores», mas quanto tempo cada consulta segura a ligação. Uma consulta de 2 segundos estraga o pool de uma forma que mil consultas de 2 ms não estragam.

2. A conta que ninguém faz

O Postgres vem de origem com max_connections = 100, e esse número é partilhado por tudo o que se liga. A conta é esta:

instâncias da aplicação × tamanho do pool
  + a sessão de psql que está aberta para ver uma coisa
  + o trabalho de migração que corre no arranque
  + a cópia de segurança noturna
  + o que mais estiver nesse servidor

Um contentor com um pool de dez usa dez. Três contentores usam trinta. Acrescente-se outra aplicação na mesma base e os cem acabam sem ninguém ter tido um pico de tráfego. O limite não se atinge por sucesso; atinge-se por multiplicação.

3. O sintoma, que engana

Há dois, e são opostos. O primeiro é honesto: too many clients already, e sabe-se logo o que é. O segundo é o mau — os pedidos ficam em fila à espera de uma ligação do pool e expiram ali, sem nunca chegarem à base.

Nesse caso a aplicação está lenta, os registos mostram timeouts de base de dados, e a base está ociosa. Quem for ver a base não encontra nada, porque o problema não está lá — está na fila à porta. É um dos casos em que os cinco comandos por esta ordem levam ao sítio errado se não se souber disto.

4. Os três números que se configuram

  • Máximo de ligações do pool. Por instância, não no total. A regra de partida: max_connections a dividir pelo número de instâncias, com folga para o psql e para as cópias.

  • Tempo de espera por uma ligação. Se não houver, o pedido fica pendurado em vez de falhar. Falhar depressa é melhor do que uma fila que cresce.

  • Tempo até fechar uma ligação ociosa. O que evita manter trinta ligações abertas às quatro da manhã por causa de um pico das três.

Aumentar o pool é a reação errada quase sempre. Se a fila cresce porque as consultas são lentas, um pool maior dá mais consultas lentas em simultâneo — e aí o problema passa a ser da base. É quando se vai ler o plano em vez de adivinhar.

5. Onde o pool deixa de funcionar

Em ambientes onde cada pedido arranca o seu próprio processo — serverless, funções à beira — não há pool que sirva, porque cada invocação criaria o seu. Cem invocações em paralelo são cem pools, e a base cai de imediato.

A saída é um intermediário (o PgBouncer e afins) em modo de transação, com uma consequência que convém saber antes: nesse modo não há sessão. Instruções preparadas, tabelas temporárias e SET deixam de se poder contar com, porque a ligação de trás muda entre transações.

6. E aqui?

Este site usa o adaptador do Prisma sobre o pg, sem opções de pool definidas — leva os valores por omissão. Um contentor, um pool, uma base que não tem mais nada a usá-la.

Está bem assim, e vale a pena ser exacto quanto ao motivo: está bem pela escala, não por cuidado nenhum. No dia em que houver dois contentores, ou outra aplicação na mesma base, é esta a conta a fazer primeiro — e é mais barato fazê-la agora, enquanto a resposta é óbvia, do que às duas da manhã com o site em baixo.

O resumo

O pool existe porque uma ligação é um processo. O limite esgota-se por multiplicação de instâncias, não por tráfego. E quando os pedidos expiram com a base ociosa, o problema é a fila à porta — não a base.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.