Wie wurden diese Linux-TCP-Standardeinstellungen festgelegt?

13

Ich habe in letzter Zeit einige Zeit damit verbracht, ein Problem in der Produktion aufzuspüren, bei dem das Verschwinden eines Datenbankservers poll()für einen verbundenen Client zu einem Stillstand von bis zu 2 Stunden (lange Wartezeit auf einen Aufruf in der libpq-Clientbibliothek) führte. Als ich mich mit dem Problem befasste, wurde mir klar, dass diese Kernel-Parameter nach unten korrigiert werden müssen, damit getrennte TCP-Verbindungen rechtzeitig erkannt werden:

net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15

Die vier oben genannten Werte stammen von einem Ubuntu 12.04-Computer und es sieht so aus, als wären diese Standardwerte unverändert gegenüber den aktuellen Standardwerten des Linux-Kernels .

Diese Einstellungen scheinen stark darauf ausgerichtet zu sein, eine bestehende Verbindung offen zu halten, und mit Keepalive-Tests äußerst sparsam umzugehen. AIUI, die Standardeinstellung tcp_keepalive_timevon 2 Stunden, bedeutet, dass wir, wenn wir auf eine Antwort für einen Remote-Host warten, 2 Stunden geduldig warten, bevor wir eine Keepalive-Prüfung einleiten, um sicherzustellen, dass unsere Verbindung noch gültig ist. Wenn der Remote-Host nicht auf einen Keepalive-Test reagiert, wiederholen wir diesen Keepalive-Test neunmal ( tcp_keepalive_probes) im Abstand von 75 Sekunden ( tcp_keepalive_intvl). Das sind also zusätzliche elf Minuten, bevor wir feststellen, dass die Verbindung wirklich unterbrochen ist.

Dies entspricht dem, was ich in diesem Bereich gesehen habe: Wenn ich zum Beispiel eine psqlmit einer entfernten PostgreSQL-Instanz verbundene Sitzung starte und eine Abfrage auf eine Antwort wartet, z

SELECT pg_sleep(30);

Wenn der Remote-Server dann einen schrecklichen Tod erleidet (z. B. Datenverkehr auf diesen Computer fallen lässt), wartet meine psql-Sitzung bis zu 2 Stunden und 11 Minuten, bevor sie feststellt, dass die Verbindung unterbrochen ist. Wie Sie sich vielleicht vorstellen können, verursachen diese Standardeinstellungen schwerwiegende Probleme für Code, mit dem wir während eines Datenbank-Failover-Ereignisses mit einer Datenbank gesprochen haben. Das Drehen dieser Knöpfe hat sehr geholfen! Und ich sehe, dass ich nicht alleine bin, wenn ich empfehle, diese Standardeinstellungen anzupassen.

Meine Fragen sind also:

  • Wie lange sind die Standardeinstellungen schon so?
  • Was war der ursprüngliche Grund dafür, diese TCP-Einstellungen als Standard festzulegen?
  • Ändern Linux-Distributionen diese Standardwerte?

Und jede andere Geschichte oder Perspektive auf die Begründung für diese Einstellungen wäre dankbar.

Josh Kupershmidt
quelle
Einige relevante Informationen hier ... tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
Drav Sloan
Beachten Sie, dass Sie die ersten drei pro-Verbindung im Client - Code mit den Socket - Optionen ändern können TCP_KEEPIDLE, TCP_KEEPCNTund TCP_KEEPINTVL.
Wnoise
1
@wnoise eigentlich seit Linux 2.6.37 sollte es auch möglich sein, die Socket-Option anzugeben TCP_USER_TIMEOUT, anstatt sie systemweit einzustellennet.ipv4.tcp_retries2 . Natürlich werden viele Anwendungen (wie hier PostgreSQL in meinem Beispiel) noch nicht unterstützt TCP_USER_TIMEOUT.
Josh Kupershmidt

Antworten:

6

RFC 1122 legt in Abschnitt 4.2.3.6 fest, dass die Keep-Alive-Zeit standardmäßig nicht weniger als zwei Stunden betragen darf.

wnoise
quelle
1
Schön, danke, dass du das ausgegraben hast. Ich denke, das beantwortet meistens die Frage, warum die tcp_keepalive_timeStandardeinstellung 7200 ist, obwohl ich immer noch an dem Präzedenzfall / der Erklärung für die anderen drei relevanten Einstellungen interessiert bin.
Josh Kupershmidt
Entfernen meiner Antwort, da dies die Frage beantwortet (zumindest für einen der Werte)
Coteyr
1
@coteyr Trotzdem danke ich für die Mühe. Im IIRC gab es einen interessanten Kommentar zu Ihrer Antwort, in dem darauf hingewiesen wurde, dass in früheren Linux-Kerneln der Standardwert 15 Minuten betrug. Es würde mich interessieren, wie / warum sich das auf 2 Stunden oder zunächst auf 15 Minuten geändert hat.
Josh Kupershmidt