Frage Auswirkungen der Konfiguration von vm.overcommit_memory


Mein VPS-Webserver, der auf CentOS 5.4 (Linux-Kernel 2.6.16.33-xenU) läuft, reagiert unregelmäßig (wie ein Mal im Monat oder dauert ein paar Wochen) und reagiert nicht mehr, wenn der Oom-Killer einsetzt. Die Überwachung des Servers zeigt, dass dies nicht der Fall ist normalerweise nicht genügend Speicher, nur manchmal.

Ich habe ein paar Blogs gelesen, die darauf verweisen diese Seite In diesem Abschnitt wird das Konfigurieren des Kernels zum besseren Verwalten von Überbelegung mithilfe der folgenden sysctl-Einstellungen erläutert:

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

Mein Verständnis davon (was falsch sein kann, aber ich kann keine kanonische Definition zur Klärung finden) besteht darin, dass dies verhindert, dass der Kernel Speicher über Swap + 80% des physischen Speichers zu viel Speicherplatz zuweist.

Allerdings habe ich auch gelesen etwas andere Quellen, die darauf hindeuten, dass diese Einstellungen keine gute Idee sind - obwohl die Kritiker dieses Ansatzes zu sagen scheinen: "Tu nichts, um dein System zu brechen, anstatt diesen Kludn zu versuchen" in der Annahme, dass Kausalität immer bekannt ist.

Also meine Frage ist, Was sind die Vor- und Nachteile dieses Ansatzes?, im Zusammenhang mit einem Apache2-Webserver, der ungefähr 10 Websites mit wenig Datenverkehr hostet? In meinem speziellen Fall hat der Webserver 512 MB RAM mit 1024 MB Swap Space. Dies scheint für die überwiegende Mehrheit der Zeit angemessen zu sein.


33
2018-02-22 10:43


Ursprung




Antworten:


Rahmen overcommit_ratio bis 80 ist wahrscheinlich nicht die richtige Maßnahme. Den Wert auf etwas unter 100 zu setzen ist fast immer falsch.

Der Grund dafür ist, dass Linux-Anwendungen mehr zuweisen, als sie wirklich benötigen. Sagen Sie, dass sie 8kB zuweisen, um eine paar Zeichenfolgen Text zu speichern. Nun, das sind mehrere KB ungenutzt. Anwendungen tun dies sehr und dafür ist Overcommit konzipiert.

Im Grunde wird der Kernel mit overcommit bei 100 nicht zulassen, dass Anwendungen mehr Speicher als Sie haben (swap + ram). Wenn Sie weniger als 100 einstellen, werden Sie nie den gesamten Speicher verwenden. Wenn Sie diese Einstellung festlegen, sollten Sie sie wegen des oben erwähnten Szenarios höher als 100 festlegen, was durchaus üblich ist.

Was Ihr Problem mit dem Auslösen des OOM-Killer angeht, wird das manuelle Einstellen des Overcommit wahrscheinlich nicht das Problem beheben. Die Standardeinstellung (heuristische Bestimmung) ist ziemlich intelligent.

Wenn Sie sehen möchten, ob dies wirklich die Ursache des Problems ist, schauen Sie sich an /proc/meminfo wenn der OOM-Killer läuft. Wenn du das siehst Committed_AS liegt in der Nähe CommitLimit, aber free zeigt immer noch freien Speicher an, dann können Sie die Überbelegung für Ihr Szenario manuell anpassen. Wenn Sie diesen Wert zu niedrig einstellen, startet der OOM-Killer Anwendungen, wenn Sie noch genügend freien Speicherplatz haben. Eine zu hohe Einstellung kann dazu führen, dass zufällige Anwendungen abstürzen, wenn sie versuchen, Speicher zu verwenden, dem sie zugewiesen wurden, aber nicht verfügbar sind (wenn der gesamte Speicher tatsächlich aufgebraucht ist).


28
2018-02-22 12:45



Danke - Ich versuche Dinge mit overcommit_ratio auf 100 gesetzt, um zu sehen, was passiert. Das Hauptproblem, das ich habe, ist, dass wenn Oom-Killer startet, es sshd immer tötet und mich davon abhält, auf den Server zuzugreifen und zu sehen, was vor sich geht. Ich denke, was ich wirklich brauche, ist, den Oom-Killer vom Laufen abzuhalten und einige Mittel aufzuzeichnen, was passiert, wenn es gelaufen wäre, damit ich die Ursache des Problems finden kann. - dunxd
@dunxd kannst du verwenden /proc/<PID>/oom_score_adj für diesen Zweck. Wenn Sie zum Beispiel oom_score_adj für sshd auf -1000 setzen, wird der Oom-Killer niemals sshd als Ziel verwenden, wenn er etwas töten möchte. Stoppen oom Killer ist nicht eine gute Idee, da dann Ihre Programme nicht in der Lage sind zu malloc Speicher, und sie werden sowieso sterben. - Patrick
Das wäre eine großartige Funktion, wenn die PID für eine App statisch wäre ... - dunxd
@dunxd ist geerbt. Lassen Sie Ihr Init-Skript auf sich selbst setzen, und alles, was vom Init-Skript gestartet wird, erbt es. - Patrick
Ihr 4 KB Beispiel ist falsch. Virtueller Speicher wird mit Seiten verwendet und die (kleinste) Größe einer Seite unter Linux beträgt 4 KB. Das bedeutet, dass das Speichern von ein paar Zeichen erfordert, dass 4 KB unabhängig von Überbelegungseinstellungen irgendwo zugeordnet werden müssen. Ein richtiges Beispiel für Speicher über Bindung wäre beispielsweise, dass Sie 10 KB zuweisen und nur die ersten 4100 Bytes verwenden. Das bedeutet, dass zwei 4-KB-Seiten die Daten speichern müssen und eine zusätzliche Seite nicht verwendet wird. Nicht überbordende Systeme werden immer diese dritte Seite bereit haben, Daten zu speichern, wenn die Nachfrage eintrifft, übersetzende Systeme werden dies nicht erzwingen. - jlliagre


Abschnitt 9.6 "Overcommit and OOM" in dem Dokument, das @dunxd erwähnt, ist besonders grafisch auf die Gefahren der Überkompensierung. Aber die 80Auch für mich interessant, habe ich ein paar Tests durchgeführt.

Was ich gefunden habe ist, dass die overcommit_ratio betrifft den gesamten RAM, der für ALLE Prozesse verfügbar ist. Root-Prozesse werden nicht anders behandelt als normale Benutzerprozesse.

Einstellen des Verhältnisses zu 100 oder weniger sollte die klassische Semantik liefern, wo Rückgabewerte von malloc/sbrk sind zuverlässig. Einstellen der Verhältnisse unter 100 könnte eine Möglichkeit sein, mehr RAM für nicht-prozessbezogene Aktivitäten wie Caching und so weiter zu reservieren.

Also, auf meinem Computer mit 24 GiB RAM, mit deaktiviertem Swap, 9 GiB im Einsatz, mit top zeigt

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

Hier sind einige overcommit_ratio Einstellungen und wie viel RAM mein Ram-Consumer-Programm ergattern könnte (berühre jede Seite) - in jedem Fall wurde das Programm einmal sauber beendet malloc gescheitert.

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

Das gleichzeitige Ausführen von mehreren, sogar mit einigen als root-Benutzer, hat nicht die Gesamtmenge geändert, die sie zusammen verbraucht haben. Es ist interessant, dass es die letzten 3+ GiB oder so nicht verbrauchen konnte; das free fiel nicht viel unter das, was hier gezeigt wird:

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

Die Experimente waren unordentlich - alles, was malloc im Moment nutzt alle RAM ist in der Regel zum Absturz, da viele Programmierer sind schrecklich auf Malloc Fehler in C zu überprüfen, einige populäre Sammlung Bibliotheken ignorieren es vollständig, und C ++ und verschiedene andere Sprachen sind eben schlechter.

Die meisten frühen Implementierungen von imaginärem RAM, die ich sah, betrafen einen sehr speziellen Fall, in dem ein einzelner großer Prozess - sagen wir 51% + verfügbaren Speichers - benötigt wurde fork() damit exec() etwas Unterstützungsprogramm, normalerweise ein viel, viel kleineres. Betriebssysteme mit Copy-on-Write-Semantik würden das ermöglichen fork(), aber mit der Maßgabe, dass, wenn der gegabelte Prozess tatsächlich versucht, zu viele Speicherseiten zu ändern (von denen jede dann als eine neue Seite unabhängig von dem anfänglichen großen Prozess instanziiert werden müsste), würde sie am Ende getötet werden. Der Elternprozess war nur dann in Gefahr, wenn mehr Speicher zugewiesen wurde, und konnte in einigen Fällen nur durch das Warten auf ein Bit für einen anderen Prozess zum Absturz gebracht werden und dann fortfahren. Der Kindprozess ersetzte sich in der Regel nur durch ein (typischerweise kleineres) Programm via exec() und war dann frei von der Bedingung.

Das Overcommit-Konzept von Linux ist ein extremer Ansatz, um beides zu ermöglichen fork() sowohl auftreten als auch einzelnen Prozessen erlauben, massiv zu vermitteln. OOM-Killer verursachte Todesfälle passieren asynchron, sogar für Programme, die tun die Speicherzuweisung verantwortungsvoll handhaben. Ich persönlich hasse systemweit Overcommit im Allgemeinen und der Oom-Killer im Besonderen - es fördert einen teuflischen Ansatz zur Speicherverwaltung, der Bibliotheken und durch sie jede App infiziert, die sie verwendet.

Ich würde vorschlagen, das Verhältnis auf 100 zu setzen und auch eine Swap-Partition zu haben, die im Allgemeinen nur von riesigen Prozessen genutzt wird - die oft nur einen winzigen Bruchteil des Teils von sich selbst verwenden, der in Swap gestopft wird, und somit Schützen Sie die überwiegende Mehrheit der Prozesse vor dem OOM Killer Fehlverhalten. Dies sollte Ihren Webserver sicher vor dem zufälligen Tod halten, und wenn es geschrieben wurde, zu handhaben mallocverantwortungsvoll, sogar sicher vor dem Töten selbst (aber wetten Sie nicht auf Letzteres).

Das heißt, ich benutze dies in /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

20
2018-05-25 16:28



Würden Sie empfehlen, vm.overcommit_memory auf 2 zu setzen? - Ut xD
Gute Anmerkung - das ist in der Tat, was ich benutze; Ich denke, ich habe es in meiner Antwort weggelassen, weil es schon in der Frage steht - Alex North-Keys