Django: CONN_MAX_AGE persiste las conexiones, pero no las reutiliza con PostgreSQL

16

Tengo una configuración de django usando Django 1.6.7 y Postgres 9.3 en Ubuntu 14.04 LTS.

En cualquier momento, el sitio obtiene alrededor de ~ 250 conexiones simultáneas a la base de datos PostgreSQL, que es un Quad Core Xeon E5-2670 a 2.5GHz, y tiene 16GB de ram. El promedio de carga en esa máquina en particular durante todo el día es de alrededor de 20 a 30.

Ocasionalmente, recibiré correos electrónicos en centinela sobre el tiempo de espera de las conexiones a la base de datos, y creo que habilitar algún tipo de agrupación de conexiones ayudará a mitigar este problema, así como a reducir un poco la carga en la base de datos.

Como estamos usando Django 1.6, tenemos la agrupación integrada disponible para nosotros. Sin embargo, cuando configuro CONN_MAX_AGE en 10 segundos, o 60 segundos, casi inmediatamente el número de conexiones simultáneas salta a la configuración máxima permitida (que es aproximadamente el doble de lo que normalmente vemos), y las conexiones comienzan a ser rechazadas.

Por lo tanto, parece por qué razón nunca, las conexiones SE persisten, pero NO ESTÁN ser reutilizado.

¿Cuál podría ser la causa de esto?

PD. También estamos usando gunicorn con --worker-class = eventlet. Quizás esta es la fuente de nuestros problemas?

synic
fuente

Respuestas:

18

Al experimentar un poco más, descubrí que la causa de nuestro problema era la clase de trabajador eventlet de gunicorn. Cada microthread hizo su propia conexión persistente, y no había forma de reutilizar ninguno de ellos.

Desactivar eventlet ha hecho que la carga en nuestros servidores web aumente (pero no mucho), pero la carga de postgres ahora se ha reducido a un promedio de 3. De 30.

synic
fuente
2
¡Nos acabas de salvar un montón de tiempo! Observamos exactamente el mismo comportamiento y estamos usando eventlet. Intentará cambiar a la agrupación de conexiones y ver cómo funcionará.
Silentier
3
Actualización: la agrupación de conexiones de bases de datos con pgBouncer parecía resolver el problema (todavía estamos usando eventlet)
silentser
Aparentemente también hay psycogreen: pypi.python.org/pypi/psycogreen/1.0 (no lo he probado, ya que una vez que configuré CONN_MAX_AGE en cero, nuestro sistema tarda 20 ms en hacer una conexión de base de datos, por lo que simplemente no necesitamos agrupación)
Darren
1
Me llevó algo de tiempo buscar en Google esta respuesta al mismo problema que teníamos.
Alper