Textos

Sistemas

O banco não ficou sem CPU

Publicado primeiro no LinkedIn · 2 mil reações · 86 comentários

A API aguenta 10 mil req/s. O banco aguenta 10 mil queries/s. Com 200 requisições simultâneas, tudo trava. O gargalo não era CPU, nem memória, nem rede. Eram as conexões.

O PostgreSQL cria um processo no servidor para cada conexão. Cada processo come algo entre 5 e 10 MB de RAM. Cem conexões simultâneas viram um gigabyte só para ficar de porta aberta. O max_connections padrão é 100. A máquina não estava lenta. Estava lotada de aperto de mão.

Sem pool

Cada requisição abre uma conexão, roda a query e fecha. São uns 50 ms de custo por conexão nova. Com 200 req/s o banco satura só no aperto de mão. A sua query nunca chega a ter uma chance justa.

Com pool

Vinte conexões persistentes são reaproveitadas. A requisição chega, pega uma conexão livre, consulta e devolve. Nada de teatro de conexão. A capacidade sobe porque você parou de pagar a entrada a cada ingresso.

Como eu configuro

1. Pool na aplicação

Com pg-pool, de 10 a 20 conexões por instância. Quatro instâncias: de 40 a 80 contra o banco. Dentro do limite. Mínimo 5, máximo 20, idle timeout de 30s, connection timeout de 5s. Se o pool encher, a requisição espera até cinco segundos. Esperar é melhor do que derrubar o banco.

2. PgBouncer na frente

Quando você escala instâncias, os pools somados passam do max_connections. O PgBouncer fica entre a aplicação e o Postgres e multiplexa centenas de conexões de cliente em dezenas de conexões reais. Em modo transação, a conexão real é sua só durante a transação e depois volta para o bolo. Eficiência máxima. Use quando o problema for a quantidade de instâncias, não quando você ainda nem tem pool.

3. Vigie o número

SELECT count(*) FROM pg_stat_activity. Alerta em 80% do máximo. Perto do teto, ou você tem vazamento no código ou tem um pool mentindo sobre o próprio tamanho.

4. Mate query longa

statement_timeout de 30 segundos. Query que passar disso é cancelada e a conexão é liberada. Sem isso, uma query travada segura um slot para sempre. Pool não te salva de vazamento. Ele só deixa o vazamento mais educado, até parar de ser.

Pool de conexão é o maior retorno por linha de configuração que eu conheço. Cinco linhas que mudam o que o sistema aguenta. Se o seu painel diz que o banco está "no limite" e a CPU está entediada, olhe as conexões primeiro.

Discutir no LinkedIn Padrões de cache