Esgotamento do pool de conexões Connection pool exhaustion
ID da causa db-pool · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de banco de dados (Equipe de infraestrutura)
O número de conexões abertas com o BD é fixo; quando queries lentas ocupam as conexões, as demais requisições esperam.
Por quê Queries lentas ou um pico de requisições deixam todas as conexões ocupadas → Efeito Novas requisições esperam até uma conexão ficar livre → Na tela Login em loading infinito, salvamento atrasado, timeouts
Logo após login ou manutenção, Quando junta muita gente
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de banco de dados (Equipe de infraestrutura)
O que fazer (Equipe de desenvolvimento)
Eliminar queries lentas, ajustar o tamanho do pool e o timeout de espera (sem aumentar o pool às cegas), separar pools por recurso.
O que fazer (Equipe de infraestrutura)
Verificar o máximo de conexões do BD e a folga de CPU e IOPS, conferir antes de escalar ou ativar o autoscaling se número de servidores × tamanho do pool cabe no máximo de conexões, adicionar ao monitoramento métricas de espera por conexão e por lock.
Números de referência
Estima-se o número necessário de conexões por “requisições por segundo × tempo que cada uma ocupa a conexão”. Com 2.000 requisições por segundo e 5 ms cada, em média 10 conexões ficam sempre ocupadas. Para dar conta dos picos, em geral se reserva de 2 a 3 vezes esse número. Se as queries ficam lentas e passam a 150 ms, a mesma carga precisa de 300 conexões.
No gráfico
Achata ao bater no limite · Conexões do BD em uso, tempo de espera por conexão
Onde olhar
Contar no BD o estado das conexões por servidor do jogo. No MySQL, ver Host, Command (conexões ociosas aparecem como Sleep) e Time no SHOW PROCESSLIST, além de Threads_connected, Threads_running e o número de conexões recusadas em Connection_errors_max_connections. No PostgreSQL, contar o pg_stat_activity agrupado por client_addr e state. Se a biblioteca de pool de conexões do servidor do jogo exporta o número e o tempo de espera, ver junto
Confirma se
Todas as conexões de um servidor do jogo, até o tamanho do pool, estão executando queries, com 0 conexões ociosas, e enquanto isso login e salvamento esperam. Ou o total de conexões do BD chega ao max_connections e novas conexões são recusadas
Descarta se
Lento mesmo com conexões ociosas de sobra: mais provável, latência da própria query (db-no-index, db-hot-row) ou saturação de recursos do BD
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
Aumentar o pool às cegas só aumenta o uso de CPU do BD e a disputa por locks, e todos ficam lentos juntos. Além disso, se número de servidores × tamanho do pool passar do máximo de conexões do BD, servidores novos ou reiniciados não conseguem nem abrir conexão. Isso é comum logo após autoscaling ou manutenção.
Fontes
Number Of Database ConnectionsPostgreSQL Depois que os recursos do BD se esgotam, mais conexões chegam a reduzir a vazão; ajustar as conexões ativas aos recursos e deixar o resto na fila melhora tanto a latência quanto a vazão
Too many connectionsMySQL Com todo o max_connections em uso, novas conexões são recusadas com o erro Too many connections