Wir hatten heute ein kleines Failover-Problem mit einer unserer HAProxy-VMs. Als wir uns damit befassten, stellten wir Folgendes fest:
26. Januar 07:41:45 haproxy2-Kernel: [226818.070059] __ratelimit: 10 Rückrufe unterdrückt 26. Januar 07:41:45 haproxy2-Kernel: [226818.070064] Nicht genügend Socket-Speicher 26. Januar 07:41:47 haproxy2-Kernel: [226819.560048] Nicht genügend Socket-Speicher 26. Januar 07:41:49 haproxy2-Kernel: [226822.030044] Nicht genügend Socket-Speicher
Welches, prodieser Link, hat anscheinend mit niedrigen Standardeinstellungen für zu tun net.ipv4.tcp_mem
. Daher haben wir sie gegenüber den Standardeinstellungen um das Vierfache erhöht (das ist Ubuntu Server, ich bin nicht sicher, ob die Linux-Variante eine Rolle spielt):
aktuelle Werte sind: 45984 61312 91968 neue Werte sind: 183936 245248 367872
Danach wurde uns eine bizarre Fehlermeldung angezeigt:
26. Jan 08:18:49 haproxy1 kernel: [ 2291.579726] Route-Hash-Kette zu lang! 26. Jan 08:18:49 haproxy1 kernel: [ 2291.579732] Passen Sie Ihr secret_interval an!
Psst..es ist ein Geheimnis!!
Dies hat offenbar damit zu tun, /proc/sys/net/ipv4/route/secret_interval
dass der Standardwert 600 ist und steuertregelmäßiges Leeren des Routen-Cache
Dies
secret_interval
weist den Kernel an, wie oft ALLE Routen-Hash-Einträge gelöscht werden sollen, unabhängig davon, wie neu/alt sie sind. In unserer Umgebung ist dies im Allgemeinen schlecht. Die CPU ist jedes Mal, wenn der Cache geleert wird, damit beschäftigt, Tausende von Einträgen pro Sekunde neu zu erstellen. Wir haben dies jedoch so eingestellt, dass es einmal täglich ausgeführt wird, um Speicherlecks in Schach zu halten (obwohl wir noch nie eines hatten).
Wir sind zwar gerne bereit, diesen Betrag zu reduzieren,Es scheint seltsam, zu empfehlen, den gesamten Routen-Cache in regelmäßigen Abständen zu löschen, anstatt einfach alte Werte schneller aus dem Routen-Cache zu verschieben.
Nach einigen Untersuchungen haben wir herausgefunden, /proc/sys/net/ipv4/route/gc_elasticity
welche Möglichkeit die bessere ist, um die Größe der Routentabelle unter Kontrolle zu halten:
gc_elasticity
lässt sich am besten als die durchschnittliche Bucket-Tiefe beschreiben, die der Kernel akzeptiert, bevor er mit dem Ablaufen von Routen-Hash-Einträgen beginnt. Dies hilft dabei, die Obergrenze aktiver Routen beizubehalten.
Wir haben die Elastizität von 8 auf 4 angepasst, in der Hoffnung, dass der Routen-Cache sich selbst aggressiver bereinigt.Das secret_interval
fühlt sich für uns nicht richtig an. Aber es gibt eine Menge Einstellungen und es ist unklar, welche hier wirklich der richtige Weg sind.
- /proc/sys/net/ipv4/route/gc_elasticity (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/geheimes_intervall (600)
- /proc/sys/net/ipv4/route/gc_thresh (?)
- rhash_entries (Kernelparameter, Standard unbekannt?)
Wir wollen das Linux-Routing nichtschlechter, daher haben wir ein bisschen Angst, einige dieser Einstellungen zu ändern.
Kann jemand einen Rat geben, welche Routing-Parameter für eine HAProxy-Instanz mit hohem Datenverkehr am besten angepasst werden sollten?
Antwort1
Dieses Problem ist mir noch nie begegnet. Sie sollten jedoch wahrscheinlich die Breite Ihrer Hash-Tabelle erhöhen, um ihre Tiefe zu verringern. Mit „dmesg“ sehen Sie, wie viele Einträge Sie derzeit haben:
$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
Sie können diesen Wert mit dem Kernel-Boot-Befehlszeilenparameter ändern rhash_entries
. Probieren Sie es zunächst manuell aus und fügen Sie es dann zu Ihrem lilo.conf
oder hinzu grub.conf
.
Zum Beispiel:kernel vmlinux rhash_entries=131072
Es ist möglich, dass Sie über eine sehr begrenzte Hash-Tabelle verfügen, weil Sie Ihrer HAProxy-VM nur wenig Speicher zugewiesen haben (die Routen-Hash-Größe wird je nach Gesamt-RAM angepasst).
Seien Sie in Bezug auf tcp_mem
vorsichtig. Ihre anfänglichen Einstellungen lassen mich glauben, dass Sie mit 1 GB RAM gearbeitet haben, von dem 1/3 TCP-Sockets zugewiesen werden konnte. Jetzt haben Sie 367872 * 4096 Bytes = 1,5 GB RAM TCP-Sockets zugewiesen. Sie sollten sehr vorsichtig sein, damit Ihnen nicht der Speicher ausgeht. Eine Faustregel ist, 1/3 des Speichers HAProxy, ein weiteres 1/3 dem TCP-Stack und das letzte 1/3 dem Rest des Systems zuzuweisen.
Ich vermute, dass Ihre Meldung „Nicht genügend Socket-Speicher“ von den Standardeinstellungen in tcp_rmem
und herrührt tcp_wmem
. Standardmäßig sind Ihnen für jeden Socket 64 kB für die Ausgabe und 87 kB für die Eingabe zugewiesen. Das 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 Parameter) können Sie den Speicherbedarf erheblich senken. Ich erziele gute Ergebnisse mit Werten ab 4096 für den Schreibpuffer und 7300 oder 16060 in tcp_rmem
(5 oder 11 TCP-Segmenten). Sie können diese Einstellungen ohne Neustart ändern, sie gelten jedoch nur für neue Verbindungen.
Wenn Sie Ihresysctlszu viel, der neueste HAProxy, 1.4-dev8, ermöglicht Ihnen, diese Parameter von der globalen Konfiguration aus und pro Seite (Client oder Server) zu optimieren.
Ich hoffe, das hilft!
Antwort2
Das Out of socket memory error
ist oft irreführend. Meistens ist es auf Internet-Servern nicht sonichtweisen auf ein Problem im Zusammenhang mit zu wenig Arbeitsspeicher hin. Wie ich inein Blog-Beitrag, der häufigste Grund ist die Anzahl der verwaisten Sockets. Ein verwaister Socket ist ein Socket, der keinem Dateideskriptor zugeordnet ist. Unter bestimmten Umständen gibt der Kernel die aus, Out of socket memory error
obwohl Sie 2x oder 4x vom Limit entfernt sind ( /proc/sys/net/ipv4/tcp_max_orphans
). Dies kommt bei internetbasierten Diensten häufig vor und ist völlig normal. Die richtige Vorgehensweise in diesem Fall besteht darin, die Anzahl der tcp_max_orphans
verwaisten Sockets auf mindestens das 4-Fache der Anzahl zu erhöhen, die Sie normalerweise bei Ihrem Spitzenverkehr sehen.
Hören Sie nicht auf Ratschläge, die Tuning empfehlen tcp_mem
oder tcp_rmem
es tcp_wmem
sei denn, SieWirklichwissen Sie, was Sie tun. Diejenigen, die solche Ratschläge geben, wissen das normalerweise nicht. Ihr Voodoo ist oft falsch oder ungeeignet für Ihre Umgebung und wird Ihr Problem nicht lösen. Es könnte es sogar noch schlimmer machen.
Antwort3
Einige dieser Parameter passen wir regelmäßig an. Unser Standard für Handelsplattformen mit hohem Durchsatz und geringer 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