Frage Tuning Linux IP-Routing-Parameter - secret_interval und tcp_mem


Wir hatten heute ein kleines Failover-Problem mit einer unserer HAProxy-VMs. Als wir uns darauf eingelassen haben, fanden wir folgendes:

Jan 26 07:41:45 haproxy2 kernel: [226818.070059] __ratelimit: 10 Rückrufe unterdrückt
Jan 26 07:41:45 haproxy2 kernel: [226818.070064] Kein Socketspeicher mehr
Jan 26 07:41:47 haproxy2 kernel: [226819.560048] Aus Socket-Speicher
Jan 26 07:41:49 haproxy2 kernel: [226822.030044] Kein Socket-Speicher mehr

Welche, per dieser Link, hat offenbar mit niedrigen Standardeinstellungen zu tun net.ipv4.tcp_mem. Also haben wir sie um 4x von ihren Standardwerten erhöht (das ist Ubuntu Server, nicht sicher, ob der Linux-Geschmack wichtig ist):

Aktuelle Werte sind: 45984 61312 91968
neue Werte sind: 183936 245248 367872

Danach sahen wir eine bizarre Fehlermeldung:

Jan 26 08:18:49 haproxy1 kernel: [2291.579726] Hashkette zu lange routen!
Jan 26 08:18:49 haproxy1 kernel: [2291.579732] Passe dein secret_interval an!

Shh .. es ist ein Geheimnis!! 

Das hat offenbar damit zu tun /proc/sys/net/ipv4/route/secret_interval standardmäßig 600 und steuert periodisches Leeren des Routencaches

Das secret_interval Weist den Kernel an, wie oft ALLE Route weggeblasen wird   Hash-Einträge unabhängig davon, wie neu / alt sie sind. In unserer Umwelt ist das so   generell schlecht. Die CPU wird damit beschäftigt sein, Tausende von Einträgen neu zu erstellen   Sekunde jedes Mal, wenn der Cache gelöscht wird. Wir haben dies jedoch so eingestellt, dass es einmal ausgeführt wird   Tag, um Speicherlecks in Schach zu halten (obwohl wir noch nie einen hatten).

Während wir das gerne reduzieren, Es erscheint merkwürdig, den gesamten Routencache in regelmäßigen Abständen löschen zu lassen, anstatt einfach alte Werte schneller aus dem Routen-Cache zu entfernen.

Nach einigen Nachforschungen fanden wir /proc/sys/net/ipv4/route/gc_elasticity Dies scheint eine bessere Option zu sein, um die Größe der Routentabelle in Schach zu halten:

gc_elasticity kann am besten als die durchschnittliche Bucket-Tiefe des Kerns beschrieben werden   wird akzeptieren, bevor es beginnt, die Hash-Einträge der Route zu verfallen. Das wird helfen   die obere Grenze der aktiven Routen beibehalten.

Wir haben die Elastizität von 8 auf 4 angepasst, in der Hoffnung, dass sich der Streckencache aggressiver beschneidet. Das secret_interval fühlt sich nicht richtig zu uns. Aber es gibt eine Reihe von Einstellungen und es ist unklar, welche sind wirklich der richtige Weg hier zu gehen.

  • / proc / sys / net / ipv4 / route / gc_elastizität (8)
  • / proc / sys / net / ipv4 / route / gc_interval (60)
  • / proc / sys / net / ipv4 / route / gc_min_interval (0)
  • / proc / sys / net / ipv4 / route / gc_timeout (300)
  • / proc / sys / net / ipv4 / route / geheim_interval (600)
  • / proc / sys / net / ipv4 / route / gc_thresh (?)
  • rhash_entries (Kernelparameter, Standard unbekannt?)

Wir wollen das Linux-Routing nicht machen schlechter, also haben wir Angst, einige dieser Einstellungen zu ändern.

Kann jemand empfehlen, welche Routing-Parameter für eine HAProxy-Instanz mit hohem Datenverkehr am besten zu tunen sind?


30
2018-01-26 20:41


Ursprung




Antworten:


Ich bin diesem Problem nie begegnet. Sie sollten jedoch Ihre Hash-Tabellenbreite erhöhen, um ihre Tiefe zu reduzieren. Mit "dmesg" sehen Sie, wie viele Einträge Sie aktuell haben:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

Sie können diesen Wert mit dem Befehlszeilenparameter kernel boot ändern rhash_entries. Probieren Sie es zuerst von Hand und fügen Sie es dann zu Ihrem lilo.conf oder grub.conf.

Zum Beispiel: kernel vmlinux rhash_entries=131072

Es ist möglich, dass Sie eine sehr eingeschränkte Hash-Tabelle haben, weil Sie Ihrer HAProxy-VM wenig Speicher zugewiesen haben (die Hash-Größe der Route wird abhängig vom Gesamt-RAM angepasst).

Über tcp_mem, Achtung. Die anfänglichen Einstellungen lassen mich glauben, dass Sie mit 1 GB RAM arbeiten, von dem 1/3 TCP-Sockets zugewiesen werden könnte. Jetzt haben Sie TCP78-Sockets 367872 * 4096 Byte = 1,5 GB RAM zugewiesen. Sie sollten sehr vorsichtig sein, um nicht aus dem Speicher zu gehen. Als Faustregel gilt, dass 1/3 des Speichers für HAProxy und 1/3 für den TCP-Stack und das letzte 1/3 für den Rest des Systems reserviert wird.

Ich vermute, dass Ihre "out of socket memory" -Meldung von den Standardeinstellungen in kommt tcp_rmem und tcp_wmem. Standardmäßig haben Sie 64 kB für jeden Socket und 87 kB am Eingang zugewiesen. Dies bedeutet insgesamt 300 kB für eine Proxy-Verbindung, nur für Socket-Puffer. Fügen Sie dazu 16 oder 32 kB für HAProxy hinzu, und Sie sehen, dass Sie mit 1 GB RAM nur 3000 Verbindungen unterstützen.

Durch Ändern der Standardeinstellungen von tcp_rmem und tcp_wmem (mittlerer Param), können Sie viel niedriger im Gedächtnis bekommen. Ich bekomme gute Ergebnisse mit Werten so niedrig wie 4096 für den Schreibpuffer und 7300 oder 16060 in tcp_rmem (5 oder 11 TCP-Segmente). Sie können diese Einstellungen ohne Neustart ändern, sie gelten jedoch nur für neue Verbindungen.

Wenn Sie es vorziehen, Ihre nicht zu berühren sysctls Zu viel, der neueste HAProxy, 1.4-dev8, erlaubt es Ihnen, diese Parameter von der globalen Konfiguration und pro Seite (Client oder Server) zu optimieren.

Ich hoffe, das hilft!


28
2018-01-26 21:37





Das Out of socket memory error ist oft irreführend. Die meiste Zeit, im Internet Server, tut es nicht Zeigen Sie ein Problem an, wenn Sie nicht genügend Arbeitsspeicher haben. Wie ich in weit mehr Details erklärt habe ein BlogeintragDer häufigste Grund ist die Anzahl der verwaisten Sockets. Ein verwaiste Socket ist ein Socket, das keinem Dateideskriptor zugeordnet ist. Unter bestimmten Umständen wird der Kernel den Out of socket memory error obwohl du 2x oder 4x vom Limit entfernt bist (/proc/sys/net/ipv4/tcp_max_orphans). Dies geschieht häufig bei Internetdiensten und ist vollkommen normal. Der richtige Weg ist in diesem Fall das Abstimmen tcp_max_orphans um mindestens das Vierfache der Anzahl der Waisenkinder zu erreichen, die Sie normalerweise mit Ihrem Hauptverkehrsaufkommen sehen.

Hören Sie nicht auf einen Ratschlag, der eine Abstimmung empfiehlt tcp_mem oder tcp_rmem oder tcp_wmem Außer du Ja wirklich weiß was du tust. Diejenigen, die diese Ratschläge geben, tun dies normalerweise nicht. Ihr Voodoo ist oft falsch oder unpassend für Ihre Umgebung und wird Ihr Problem nicht lösen. Es könnte es sogar noch schlimmer machen.


8
2018-03-15 05:43



Wenn dies geschieht, ist die Nachricht in dmesg anders, Sie sehen "zu viele verwaiste Sockets". Ich stimme Ihnen jedoch zu, dass Waisen eine große Menge an Speicher verbrauchen können. - Willy Tarreau
Wenn Sie die Anzahl von überschreiten /proc/sys/net/ipv4/tcp_max_orphans Sie werden einen anderen Fehler erfahren. Der gesamte Stack Exchange Stack zum Beispiel hat /proc/sys/net/ipv4/tcp_max_orphans bei 65536 und /proc/net/sockstat Ergebnisse in TCP: Inuse 2996 Waisen 171 Tw 15972 Allok 2998 Mem 1621 - ein Unterschied, der nicht ignoriert werden kann. - Geoff Dalgas♦


Wir stimmen einige dieser Parameter regelmäßig ab. Unser Standard für Handelsplattformen mit hohem Durchsatz und niedriger Latenz ist:

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000

-3
2018-01-26 22:25



Laut Willy's Mathematik bedeutet das, dass dein Standardgedächtnisdruck # (mittlere Zahl) 68 GB ist ?! Mal drei (rmem, wmem, mem) ?? - Jeff Atwood
Diese Tunablets sind falsch und werden sehr häufig in Bankumgebungen gefunden und dann blind kopiert. Sie werden kein Problem mit nur wenigen gleichzeitigen Sitzungen haben, aber selbst mit 100 TCP-Sockets werden Sie 3,2 GB RAM zuweisen. Solange die Latenz niedrig ist, werden Sie nichts Verdächtiges bemerken. Sie müssen nur während einer Übertragung eine entfernte Maschine trennen, um zu sehen, dass die Ausgabepuffer gefüllt sind, oder eine lokale Aufgabe einfrieren und die Füllung des Eingabepuffers sehen. Das ist verrückt... - Willy Tarreau
Jeff, das ist nicht mal drei. tcp_mem ist in Seiten und definiert die globale Größe. tcp_rmem und tcp_wmem sind in Bytes und definieren die Größe pro Socket. - Willy Tarreau