Django: CONN_MAX_AGE persiste conexões, mas não as reutiliza com PostgreSQL

16

Eu tenho uma configuração de django usando Django 1.6.7 e Postgres 9.3 no Ubuntu 14.04 LTS.

A qualquer momento, o site obtém cerca de 250 conexões simultâneas ao banco de dados PostgreSQL, que é um Quad Core Xeon E5-2670 a 2.5GHz e tem 16GB de RAM. A média de carga nessa máquina específica ao longo do dia é de 20 a 30.

Ocasionalmente, recebo emails em sentinela sobre o tempo limite das conexões com o banco de dados, e acho que ativar algum tipo de pool de conexões ajudará a atenuar esse problema, além de diminuir um pouco a carga no banco de dados.

Como estamos usando o Django 1.6, temos o pool incorporado disponível para nós. No entanto, quando defino CONN_MAX_AGE como 10 segundos ou 60 segundos, quase imediatamente o número de conexões simultâneas salta para a configuração máxima permitida (que é aproximadamente o dobro do que geralmente vemos) e as conexões começam a ser rejeitadas.

Assim, parece por que razão nunca, as conexões SÃO persistindo, mas eles NÃO SÃO sendo reutilizado.

Qual poderia ser a causa disso?

PS. Também estamos usando gunicorn com --worker-class = eventlet. Talvez essa seja a fonte de nossos problemas?

synic
fonte

Respostas:

18

Fazendo mais algumas experiências, descobri que a causa do nosso problema era realmente a classe de trabalhadores de eventos de gunicorn. Cada microtread fez sua própria conexão persistente e não havia como reutilizar nenhum deles.

A desativação do eventlet aumentou a carga em nossos servidores da Web (mas não muito), mas a carga do postgres agora caiu para uma média de 3. A partir de 30.

synic
fonte
2
Você acabou de economizar uma tonelada de tempo! Observamos exatamente o mesmo comportamento e estamos usando o eventlet. Tentará mudar para o pool de conexões e ver como isso funcionará.
silentser
3
Update: pool de conexões de banco de dados com pgBouncer parecia resolver o problema (ainda estamos usando eventlet)
silentser
Aparentemente, há também psycogreen: pypi.python.org/pypi/psycogreen/1.0 (eu não tentei assim que defini o CONN_MAX_AGE para zero, leva 20 segundos para o sistema fazer uma conexão com o banco de dados, então simplesmente não precisamos de pool)
Darren
1
Levei algum tempo pesquisando no Google para encontrar essa resposta exatamente no mesmo problema que estávamos tendo.
Alper