Django: CONN_MAX_AGE persiste les connexions, mais ne les réutilise pas avec PostgreSQL

17

J'ai une configuration django qui utilise Django 1.6.7 et Postgres 9.3 sur Ubuntu 14.04 LTS.

À tout moment, le site obtient environ 250 connexions simultanées à la base de données PostgreSQL, qui est un Quad Core Xeon E5-2670 à 2,5 GHz et dispose de 16 Go de RAM. La charge moyenne sur cette machine particulière tout au long de la journée est d'environ 20 à 30.

Parfois, je reçois des e-mails en sentinelle sur les connexions expirant vers la base de données, et je pense qu'activer une sorte de regroupement de connexions aidera à atténuer ce problème, ainsi qu'à réduire un peu la charge sur la base de données.

Puisque nous utilisons Django 1.6, nous avons le pooling intégré à notre disposition. Cependant, lorsque j'ai défini CONN_MAX_AGE sur 10 secondes ou 60 secondes, presque immédiatement le nombre de connexions simultanées atteint le paramètre maximum autorisé (qui est environ le double de ce que nous voyons habituellement) et les connexions commencent à être rejetées.

Donc, il semble que pour quelque raison que ce soit, les connexions SONT persistantes, mais NE SONT PAS réutilisées.

Quelle pourrait en être la cause?

PS. Nous utilisons également gunicorn avec --worker-class = eventlet. C'est peut-être la source de nos malheurs?

synique
la source

Réponses:

18

En faisant un peu plus d'expérimentation, j'ai découvert que la cause de notre problème était en effet la classe des ouvriers eventlet de gunicorn. Chaque micro-fil a créé sa propre connexion persistante, et il n'y avait aucun moyen de réutiliser l'un d'eux.

La désactivation de l'eventlet a fait augmenter la charge sur nos serveurs Web (mais pas beaucoup), mais la charge postgres est maintenant tombée à une moyenne de 3. De 30.

synique
la source
2
Vous venez de nous faire gagner une tonne de temps! Nous observons exactement le même comportement et nous utilisons eventlet. J'essaierai de passer au regroupement de connexions et de voir comment cela fonctionnera.
silentser
3
Mise à jour: la mise en commun des connexions à la base de données avec pgBouncer semble résoudre le problème (nous utilisons toujours eventlet)
silentser
Apparemment, il y a aussi psycogreen: pypi.python.org/pypi/psycogreen/1.0 (je ne l'ai pas essayé car une fois que j'ai mis CONN_MAX_AGE à zéro, il faut 20 ms à notre système pour établir une connexion DB, nous n'avons donc tout simplement pas besoin de mise en commun)
Darren
1
Il m'a fallu un certain temps sur Google pour trouver cette réponse au même problème que nous rencontrions.
Alper