Methoden zum Konfigurieren des Linux Out-of-Memory Killers
von Robert Chase
Veröffentlicht Februar 2013
In diesem Artikel wird der Linux out-of-memory (OOM)-Killer beschrieben und wie Sie herausfinden können, nach welchen Kriterien der OOM-Killer entscheidet, welche Prozesse abgebrochen werden sollen. In dem Artikel werden auch Methoden zum Konfigurieren des OOM-Killers beschrieben, die dazu dienen den Anforderungen vieler verschiedener Umgebungen besser gerecht zu werden..
Informationen zum OOM-Killer
Wenn ein Server, der eine Datenbank oder einen Anwendungsserver unterstützt, crasht, dann beginnt oft ein Wettrennen, um die kritischen Systeme so schnell wie möglich wieder zum Laufen zu bringen, vor allem wenn es sich dabei um ein wichtiges Produktionssystem handelt. Dabei bleibt die Ursache des plötzlichen Funktionsausfalls der Anwendung oder Datenbank oft ein Rätsel. Manchmal kann als Ursache ausgemacht werden, dass das System zu wenig Arbeitsspeicher besitzt und einen wichtigen Prozess abbricht, um betriebsfähig zu bleiben.
Der Linux Kernel ist dafür verantwortlich an alle auf dem System betriebenen Anwendungen Arbeitsspeicher zu vergeben, wenn dieser angefordert wird. Aber weil viele Anwendungen schon vorher Speicher anfordern und dann nicht immer den gesamten ihnen zugeordneten Speicherplatz nutzen, wurde der Kernel so entwickelt, dass er mehr Speicher vergeben kann, als zur Verfügung steht, um die Nutzung des Speichers so effizient wie möglich zu gestalten. Diese Funktion der Speichermehrfachvergabe, auch Memory Overcommit genannt, ermöglicht es dem Kernel mehr Speicherplatz zu vergeben, als letztendlich physisch zur Verfügung steht. Wenn ein Prozess den an ihn vergebenen Speicherplatz wirklich ganz nutzt, dann vergibt der Kernel diese Ressourcen an die Anwendung. Wenn zu viele Anwendungen den an sie vergebene Speicher nutzen, dann passiert es, dass das Overcommit-Modell an seine Grenzen stößt und der Kernel, Prozesse "töten" muss, um weiterhin betriebsfähig sein zu können. Den Mechanismus, den der Kernel verwendet, um Speicher auf dem System wiederzugewinnen, wird als Out-Of-Memory-Killer oder kurz gesagt OOM-Killer bezeichnet.
Herausfinden warum ein Prozess abgebrochen wurde
Bei der Problemsuche in Fällen, bei denen der OOM-KIller eine Anwendungen abgebrochen hat, gibt es verschiedene Anhaltspunkte um zu einer Lösung zu gelangen. Im nachfolgenden Beispiel möchten wir uns einmal unseren syslog näher ansehen, um herauszufinden, ob wir die Ursache für unser Problem finden können. Der oracle-Prozess wurde vom OOM-Killer abgebrochen, weil es zu einem OOM-Vorfall kam. Der Großbuchstabe K in Killed deutet darauf hin, dass der Prozess über ein -9-Signal abgebrochen wurde. Dies ist ein sicheres Zeichen dafür, dass es sich in diesem Fall um ein Problem mit dem OOM-Killer handeln könnte.
grep -i kill /var/log/messages*
host kernel: Out of Memory: Killed process 2592 (oracle).
Wie können also nun den Status von niedriger und hoher Speichernutzung anhand eines Systems untersuchen. Dabei ist es wichtig zu beachten, dass diese Werte reellen Werten entsprechen und sich je nach Belastung des Systems ändern: aus diesem Grund sollten die Werte regelmäßig und häufig geprüft werden, bevor der Druck auf den Speicher entsteht. Dabei ist es wichtig, diese Werte vor dem Abbrechen eines Prozesses zu prüfen. Wenn wir uns die Werte ansehen, nachdem der Prozess abgebrochen wurde, hilft uns das in unserer Untersuchung nicht weiter.
[root@test-sys1 ~]# free -lm
total used free shared buffers cached
Mem: 498 93 405 0 15 32
Low: 498 93 405
High: 0 0 0
-/+ buffers/cache: 44 453
Swap: 1023 0 1023
Auf dieser Test-virtuellen Machine haben wir 498 MB freien Arbeitsspeicher. Das System besitzt keine Auslagerungsdatei (Swap usage). Der -l-Schalter zeigt Statistiken zu hohem und niedrigem Speicher an, und der -m-Schalter gibt die Ausgabe in Megabyte an, um das Lesen zu erleichtern.
[root@test-sys1 ~]# egrep 'High|Low' /proc/meminfo
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 510444 kB
LowFree: 414768 kB
Die gleichen Daten können durch Prüfung erhalten werden /proc/memory und indem wir speziell auf die hohen und niedrigen Werte schauen. Bei dieser Methode erhalten wir jedoch keine Swap-Informationen von der Ausgabe und die Ausgabe erfolgt in Kilobyte.
Mit niedriger Speicher ist der Speicher gemeint, auf den der Kernel direkten physischen Zugriff hat. Mit hoher Speicher ist der Speicher gemeint, bei dem der Kernel keine direkte physische Adresse hat und der daher über eine virtuelle Adresse zugeordnet werden muss. Auf älteren 32-Bit-Systemen wird aufgrund der Art und Weise, wie der Speicher einer virtuellen Adresse zugeordnet wird, ein niedriger und ein hoher Arbeitsspeicher angezeigt. Auf 64-Bit-Plattformen wird kein virtueller Adressraum benötigt und der gesamte Systemspeicher wird als niedriger Speicher angezeigt.
Wenn wir /proc/memory betrachten und den free-Befehl eingeben, erhalten wir nützliche Informationen zum „momentanen“ Speicherverbrauch. Es gibt aber auch Fälle, in denen wir die Speichernutzung über einen längeren Zeitraum untersuchen möchten. Der vmstat-Befehl ist dafür sehr hilfreich.
Im Beispiel in Listing 1 verwenden wir den vmstat-Befehl, um unsere Ressourcen 10-mal alle 45 Sekunden zu überprüfen. Der Schalter -S zeigt unsere Daten in einer Tabelle an, und der Schalter -M zeigt die Ausgabe in Megabyte an, um die Lesbarkeit zu verbessern. Wie Sie sehen, verbraucht etwas unseren freien Speicher, aber wir verwenden die Swapping-Funktion in diesem Beispiel noch nicht.
[root@localhost ~]# vmstat -SM 45 10
procs -----------memory-------- ---swap-- -----io-- --system-- ----cpu---------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 221 125 42 0 0 0 0 70 4 0 0 100 0 0
2 0 0 192 133 43 0 0 192 78 432 1809 1 15 81 2 0
2 1 0 85 161 43 0 0 624 418 1456 8407 7 73 0 21 0
0 0 0 65 168 43 0 0 158 237 648 5655 3 28 65 4 0
3 0 0 64 168 43 0 0 0 2 1115 13178 9 69 22 0 0
7 0 0 60 168 43 0 0 0 5 1319 15509 13 87 0 0 0
4 0 0 60 168 43 0 0 0 1 1387 15613 14 86 0 0 0
7 0 0 61 168 43 0 0 0 0 1375 15574 14 86 0 0 0
2 0 0 64 168 43 0 0 0 0 1355 15722 13 87 0 0 0
0 0 0 71 168 43 0 0 0 6 215 1895 1 8 91 0 0
Listing 1
Die Ausgabe von vmstat kann mit dem folgenden Befehl in eine Datei umgeleitet werden. Wir können sogar Dauer und Häufigkeit der Überwachung anpassen, um länger zu überwachen. Während der Befehl ausgeführt wird, können wir jederzeit die Ausgabedatei anzeigen, um die Ergebnisse anzuzeigen.
Im folgenden Beispiel wird der Speicher 1000 Mal alle 120 Sekunden betrachtet. Das & am Ende der Zeile ermöglicht es uns, dies als Prozess auszuführen und zu unserem Terminal zurückzukehren.
vmstat -SM 120 1000 > memoryusage.out &
Zu Referenzzwecken zeigt Listing 2 einen Ausschnitt aus der Manpage vmstat, die zusätzliche Informationen zur Ausgabe des Befehls enthält. Diese Informationen sind nur die speicherbezogenen Informationen. Der Befehl enthält auch Informationen zu Festplatten-E / A und zur CPU-Auslastung.
Memory
swpd: the amount of virtual memory used.
free: the amount of idle memory.
buff: the amount of memory used as buffers.
cache: the amount of memory used as cache.
inact: the amount of inactive memory. (-a option)
active: the amount of active memory. (-a option)
Swap
si: Amount of memory swapped in from disk (/s).
so: Amount of memory swapped to disk (/s).
Listing 2
Es gibt eine Reihe anderer Tools zur Überwachung des Speichers und der Systemleistung, die dafür verwendet werden können derartige Probleme zu untersuchen. Tools wie sar (System Activity Reporter) und dtrace (Dynamic Tracing) sind sehr nützlich, um bestimmte Daten über die Systemleistung im Zeitverlauf zu sammeln. Für noch mehr Transparenz verfügen die dtrace-Stabilitäts- und -Datenstabilitätsprüfungen sogar über einen Trigger für OOM-Bedingungen, der ausgelöst wird, wenn der Kernel einen Prozess aufgrund einer OOM-Bedingung beendet. Weitere Informationen zu dtrace und sar finden Sie im Abschnitt „Siehe auch” dieses Artikels.
Es gibt verschiedene Situationen, die ein OOM-Ereignis auslösen, die nicht darauf zurückzuführen sind, dass das System keinen RAM-Speicher mehr hat und nicht genug Platz auf der Austauschdatei aufgrund von hoher Auslastung, vorhanden ist. So kann es sein, dass der Kernel den Swap-Speicher (Austauschspeicher) aufgrund der Art der Arbeitslast auf dem System möglicherweise nicht optimal nutzen kann. Anwendungen, die mlock() oder HugePages verwenden, verfügen über Speicher, der nicht auf die Festplatte ausgelagert werden kann, wenn das System nur noch über wenig physischen Speicher verfügt. Außerdem kann es sein, dass Kernel-Datenstrukturen zu viel Speicherplatz beanspruchen, die wiederum den Speicher auf dem System überlasten und so einen OOM-Vorfall auslösen. Bei vielen auf der NUMA-Architektur basierenden Systemen können OOM-Vorfälle ausgelöst werden, wenn einem Knoten der Speicher ausgeht und daraufhin ein OOM im Kernel ausgelöst wird, obwohl in den verbleibenden Knoten noch viel Speicher übrig ist. Weitere Informationen zu OOM-Vorfällen auf Computern mit NUMA-Architektur finden Sie im Abschnitt "Sehen Sie auch den "Abschnitt dieses Artikels.
Konfigurieren des OOM-Killers
Der Linux OOM-Killer verfügt über mehrere Konfigurationsoptionen, mit denen Entwickler auswählen können, wie sich das System verhalten soll, wenn der Speicher nicht ausreicht. Diese Einstellungen und Auswahlmöglichkeiten variieren je nach Umgebung und Anwendungen, die das System darauf konfiguriert hat.
Hinweis: Es wird empfohlen, Tests und Optimierungen in einer Entwicklungsumgebung durchzuführen, bevor Änderungen an wichtigen Produktionssystemen vorgenommen werden.
In einigen Umgebungen, in denen ein System eine einzelne kritische Aufgabe ausführt, kann ein Neustart eine gute Option zur Behebung eines OOM-Vorfalls sein. Durch einen Neustart kann das System ohne Eingreifen des Administrators schnell wieder in den Betriebszustand versetzt werden. Obwohl dies kein optimaler Ansatz ist, gibt es eine Logik dahinter, die darin besteht, dass ein Neustart des Systems die Anwendung wiederherstellt, da unsere Anwendung beim Systemneustart zusammen mit dem System wiederhergestellt wird. Dies ist vor allem dann der Fall, wenn unsere Anwendung durch den OOM-Killer abgebrochen wurde und nicht ausgeführt werden kann. Ein manueller Neustart der Anwendung durch einen Administrator wird nicht den gleichen Erfolg bescheren.
Die folgenden Einstellungen lösen eine Systempanik aus und führen dazu, dass das System bei einem OOM-Vorfall neu gestartet wird Die Befehle sysctl konfigurieren dies in Echtzeit. Durch Anhängen der Einstellungen an sysctl.conf bleiben diese Einstellungen auch nach einem Neustart erhalten. Der Wert X für kernel.panic ist die Anzahl der Sekunden, nach denen das System neu gestartet werden soll. Diese Einstellung sollte an die Anforderungen Ihrer Umgebung angepasst werden.
sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf
Wir können auch einstellen, wie der OOM-Killer mit OOM-Vorfällen mit bestimmten Prozessen umgeht. Nehmen wir zum Beispiel unseren oracle-Prozess 2592, der zuvor beendet wurde. Wenn wir die Wahrscheinlichkeit verringern möchten, dass unser oracle-Prozess vom OOM-Killer beendet wird, können wir Folgendes tun.
echo -15 > /proc/2592/oom_adj
Wir können die Wahrscheinlichkeit erhöhen, dass der OOM-Killer unseren oracle-Prozess beendet, indem wir Folgendes tun.
echo 10 > /proc/2592/oom_adj
Wenn wir unseren oracle-Prozess vom OOM-Killer ausschließen möchten, können wir Folgendes tun, wodurch er vollständig vom OOM-Killer ausgeschlossen wird. Dabei ist es wichtig zu beachten, dass diese Vorgehensweise abhängig von den Ressourcen und der Konfiguration des Systems zu unerwartetem Verhalten führen kann. Wenn der Kernel einen Prozess mit viel Speicher nicht beenden kann, greift er auf andere verfügbare Prozesse zu. Manche dieser Prozesse können wichtige Betriebssystem-Prozesse sein, die letztendlich zum Ausfall des Systems führen können.
echo -17 > /proc/2592/oom_adj
Wir können gültige Bereiche für oom_adj von -16 bis +15 festlegen, wobei eine Einstellung von -17 einen Prozess vollständig vom OOM-Killer ausnimmt. Je höher die Zahl, desto wahrscheinlicher ist es, dass unser Prozess beendet wird, wenn bei dem System ein OOM-Vorfall ausgelöst wird. Der Inhalt von /proc/2592/oom_score kann ebenfalls angezeigt werden, um herauszufinden, wie wahrscheinlich es ist, dass ein Prozess vom OOM-Killer beendet wird. Eine Punktzahl von 0 ist ein Hinweis darauf, dass unser Prozess vom OOM-Killer ausgenommen ist. Je höher der OOM-Score ist, desto wahrscheinlicher ist es, dass ein Prozess bei einem OOM-Vorfall abgebrochen wird..
Der OOM-Killer kann mit dem folgenden Befehl vollständig deaktiviert werden. Diese Vorgehensweise wird für Produktionsumgebungen nicht empfohlen, da bei Auftreten eines Speichermangels abhängig von den verfügbaren Systemressourcen und der Konfiguration unerwartetes Verhalten des Systems auftreten kann. Dieses unerwartete Verhalten kann von einer Kernel-Panik bis zu einem Aufhängen des Systems reichen, abhängig von den Ressourcen, die dem Kernel zum Zeitpunkt des OOM-Vorfalls zur Verfügung stehen.
sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
Es gibt Umgebungen, wo diese Einstellungen weniger als optimal funktionieren. In diesen Fällen können weitere Konfigurationen und Einstellungen Abhilfe schaffen. Das Konfigurieren von HugePages für Ihren Kernel kann bei OOM-Problemen helfen. Der Erfolg der Konfiguration ist abhängig von den Anforderungen der auf dem System ausgeführten Anwendungen.
Siehe auch
Hier finden Sie einige zusätzliche Ressourcen zu HugePages, dtrace, sar und OOM für NUMA-Architekturen:
Informationen zu HugePages auf My Oracle Support (Anmeldung erforderlich): HugePages auf Linux: Was es ist ... und was es nicht ist ... [ID 361323.1]
Über den Autor
Robert Chase ist Mitglied des Oracle Linux Produktmanagementteams. Er beschäftigt sich seit 1996 mit Linux und Open Source-Software. Er hat in seiner bisherigen Laufbahn sowohl mit ganz kleinen Systemen wie eingebetteten Geräten und mit großer Hardware der Supercomputer-Klasse, gearbeitet.
Revision 1.0, 02/19/2013