pgBouncer funktioniert hervorragend, ist aber gelegentlich nicht mehr verfügbar


9

Ich führe pgBouncer vor einer ausgelasteten Postgres 9-Datenbank aus. Meistens funktioniert es gut. Aber alle paar Stunden erhalte ich eine Fehler-E-Mail von meiner Anwendung, mit Ausnahme von psycopg2:

OperationalError ('Verbindung zum Server konnte nicht hergestellt werden: Angeforderte Adresse kann nicht zugewiesen werden. Wird der Server auf dem Host "neo-hulk" ausgeführt und akzeptiert TCP / IP-Verbindungen auf Port 6432?')

Dies ist eine Python-App mit einer Reihe von Sellerie-Arbeitern, die Aufgaben ausführen. Wenn diese Fehler auftreten, überprüfe ich die pgbouncer-Datenbank und die Poolgröße ist in Grenzen. Nach einigen Experimenten habe ich die maximale Poolgröße auf 400 und die Poolgröße auf 200 festgelegt. Der Poolmodus ist "Sitzung" (Anforderungen werden meistens automatisch festgeschrieben, fast keine Transaktionen).

Was lässt pgBouncer so "verschwinden"? Es ist nur für kurze Zeiträume (und insgesamt sprechen wir über eine winzige Anzahl von Anfragen im Vergleich zu der Menge an Anfragen, die es bearbeitet), aber diejenigen Anfragen, die fehlschlagen, sind wichtig.

Vielen Dank!


Betriebssystem und Version? Kernel-Version wenn Linux? Genaue PostgreSQL- und PgBouncer-Versionen? Haben Sie PgBouncer in der Debug-Protokollstufe ausgeführt und festgestellt, ob es nützliche Informationen enthält?
Craig Ringer

Debian 6. Linux Version 2.6.32-5-amd64 (Debian 2.6.32-48squeeze1) pgbouncer Version 1.5.4 Postgres 9.1. Das Protokoll protokolliert nicht das Verbinden / Trennen, da ich dachte, es sei ein bisschen viel, aber es sind keine Fehler vorhanden, wenn diese App-Fehler ausgelöst werden. Der Fehler kommt von psycopg2 zu denken, dass es keinen Datenbankserver gibt, mit dem man sprechen kann, obwohl dieses Problem vor pgbouncer nicht existierte
Harel

1
Hm, also aktueller PgBouncer und der Kernel ist uralt aber ziemlich stabil. Ich denke, Sie müssen eine detailliertere Protokollierung in PgBouncer mit aktivieren -vvvund prüfen, ob Sie die anomale Protokollausgabe rechtzeitig mit Ihren Fehlern abgleichen können.
Craig Ringer

Ich habe ein "set verbose = 1; reload;" in der pgbouncer-Shell und konnte im Protokoll nichts Außergewöhnliches finden. Dies ist ein Produktionssystem, daher konnte der Dienst nicht gestoppt werden, um als Nicht-Daemon mit -vvv ausgeführt zu werden. Hoffentlich habe ich das gleiche Ergebnis. Beachten Sie, dass der Fehler darauf hindeutet, dass überhaupt keine Verbindung zu pgbouncer hergestellt werden konnte, dh, dass er in diesem Port nicht empfangsbereit ist. Es werden ständig Tausende von Verbindungen hergestellt und es ist seltsam, dass eine kleine Anzahl von ihnen so versagt.
Harel

Tricky; es klingt wie eine mögliche Rennbedingung, aber in was / wo ...
Craig Ringer

Antworten:


15

Der Teil " Angeforderte Adresse kann nicht zugewiesen werden " in der Fehlermeldung stammt vom Kernel-TCP-Stack. Wenn dies zeitweise auftritt, bedeutet dies normalerweise, dass der Speicherplatz der verfügbaren Steckdosen aufgrund zu vieler Steckdosen im Wartezustand ( TIME_WAIToder weniger wahrscheinlich FIN_WAIT_1oder FIN_WAIT_2) erschöpft ist.

Der Bereich der Socket-Ports kann von ausgegeben werden cat /proc/sys/net/ipv4/ip_local_port_range. Der Standardwert für einen Standard-Linux-Kernel ist im Allgemeinen 32768 61000.

Sie können das Ergebnis netstat -ton|grep WAITauf den Clients und auf dem Host des pgBouncer überprüfen, wenn das System ausgelastet ist. Das -oFlag zeigt die Zeitüberschreitungszähler an, die sich auf Wartezustände beziehen.

Wenn die Gesamtzahl der TCP-Sockets nahe beieinander liegt, 61000-32768=28232ist die Erschöpfung dieses Bereichs wahrscheinlich Ihr Problem. Da ein geschlossener Socket TIME_WAITim Normalzustand 60 Sekunden im Status verbringt , schlagen neue Verbindungen mit dem genannten Fehler fehl, bis Ports freigegeben werden, wenn ein Client-Host in einer Minute mehr als 28232 Mal eine Verbindung herstellt.

Als erste Problemumgehung kann der Bereich der TCP-Ports erweitert werden:

 # echo "1025 65535" >/proc/sys/net/ipv4/ip_local_port_range

Wenn es nicht zufriedenstellend ist, überprüfen Sie die tcp_tw_recycleund tcp_tw_reuse-Flaggen, die auch durch /proc/sys/net/ipv4und eingestellt werden können sysctl.

Sie sind definiert als (von man tcp):

       tcp_tw_recycle (Boolean; Standard: deaktiviert; seit Linux 2.4)
              Ermöglichen Sie das schnelle Recycling von TIME_WAIT-Sockets. Aktivieren Sie dies
              Option wird nicht empfohlen, da dies Probleme bei der Arbeit verursacht
              mit NAT (Network Address Translation).

       tcp_tw_reuse (Boolean; Standard: deaktiviert; seit Linux 2.4.19 / 2.6)
              Ermöglichen Sie die Wiederverwendung von TIME_WAIT-Sockets für neue Verbindungen, wenn dies der Fall ist
              sicher aus protokollsicht. Es sollte nicht ohne geändert werden
              Beratung / Anfrage von technischen Experten.

Persönlich hatte ich Erfolg mit tcp_tw_recyclediesem Problem mit einer MySQL-Client-App, aber nehme dies nicht als Empfehlung, da mein Verständnis von TCP bestenfalls oberflächlich ist.


1
Diese Antwort zeigt alles, was das oberflächliche Verständnis von TCP betrifft. Danke für das. Ich habe den Portbereich vergrößert und ihn eine Weile laufen lassen, um zu sehen, ob er Auswirkungen hat. (Muss ich neu starten, nachdem ich es eingestellt habe?)
Harel

Ich denke, die Port-Erhöhung hat es geschafft. Bisher habe ich keinen Fehler erhalten. Eine grobe Zählung der Netstat-Zeilen zeigt im Client nahezu 20.000 an, sodass von dort bis zum Standardlimit von 28 KB nicht mehr lange dauert. Dank dafür!
Harel

1
Gut! Sie möchten die Einstellung /etc/sysctl.confso einstellen net.ipv4.ip_local_port_range = 1025 65535, dass sie auch nach einem Neustart erhalten bleibt.
Daniel Vérité

Vielen Dank. Ich habe seitdem Fehler erhalten, aber nicht diesen, also ist das immer noch gut. Wenn Sie es einige Tage laufen lassen, ändert sich die Dauerwelle. Ich bin froh, dass dies bisher zu funktionieren scheint, weil die anderen Änderungen mir Angst machen :)
Harel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.