J'exécute pgBouncer devant une base de données Postgres 9 occupée. Pour la plupart du temps, cela fonctionne bien. Mais toutes les quelques heures, je recevrai un e-mail d'erreur de mon application, à l'exception de psycopg2:
OperationalError ('impossible de se connecter au serveur: impossible d'attribuer l'adresse demandée Le serveur fonctionne-t-il sur l'hôte "neo-hulk" et accepte-t-il les connexions TCP / IP sur le port 6432?')
Il s'agit d'une application python avec un tas de travailleurs céleri exécutant des tâches. Lorsque ces erreurs arrivent, je vérifie la base de données pgbouncer et la taille du pool est dans les limites. Après quelques expérimentations, j'ai défini la taille maximale du pool sur 400 et la taille du pool sur 200. Le mode pool est "session" (les demandes sont principalement auto-validées, presque aucune transaction).
Qu'est-ce qui fait que pgBouncer «disparaît» ainsi? ce n'est que pour de courtes périodes de temps (et au total, nous parlons d'une petite quantité de demandes par rapport au volume de demandes qu'elle traite), mais les demandes qui échouent sont importantes.
Merci!
la source
-vvv
et voir si vous pouvez faire correspondre la sortie de journal anormale avec vos erreurs dans le temps.Réponses:
La partie " Impossible d'attribuer l'adresse demandée " dans le message d'erreur provient de la pile TCP du noyau. Lorsqu'il est rencontré par intermittence, cela signifie généralement que l'espace des sockets disponibles est épuisé en raison de trop de sockets en état d'attente (
TIME_WAIT
, ou moins probablementFIN_WAIT_1
ouFIN_WAIT_2
)La plage de ports de socket peut être sortie par
cat /proc/sys/net/ipv4/ip_local_port_range
. La valeur par défaut sur un noyau Linux stock est généralement32768 61000
.Vous pouvez vérifier le résultat de
netstat -ton|grep WAIT
sur le (s) client (s) et sur l'hôte pgBouncer lorsque le système est occupé. L'-o
indicateur affichera les compteurs de délai d'attente liés aux états d'attente.Si le nombre total de sockets TCP est proche, l'
61000-32768=28232
épuisement de cette plage est probablement votre problème. Puisqu'un socket fermé passe 60 secondes à l'TIME_WAIT
état normal, si un hôte client se connecte plus de 28232 fois en une minute, les nouvelles connexions échoueront avec l'erreur mentionnée jusqu'à ce que les ports soient libérés.Comme première solution, la plage de ports TCP peut être étendue:
Si ce n'est pas satisfaisant, vérifiez les drapeaux
tcp_tw_recycle
ettcp_tw_reuse
, également réglables via/proc/sys/net/ipv4
etsysctl
.Ils sont définis comme (de
man tcp
):Personnellement, j'ai eu du succès
tcp_tw_recycle
face à ce problème avec une application cliente MySQL, mais ne prenez pas cela comme une recommandation, ma compréhension de TCP étant au mieux superficielle.la source
/etc/sysctl.conf
manièrenet.ipv4.ip_local_port_range = 1025 65535
à ce qu'il persiste lors des redémarrages.