Speicherüberbuchung richtig einstellen
Die Warnung 'overcommit_memory is set to 0, background save may fail' beim Start von Redis gehört zu den häufigsten Kernel-Tuning-Hinweisen in Magento-Hosting-Umgebungen. Wer die drei Overcommit-Modi und ihren Zusammenhang mit dem OOM-Killer versteht, trifft die richtige Entscheidung statt blind einer Copy-Paste-Empfehlung zu folgen.
Inhaltsverzeichnis
- 1. Was Speicherüberbuchung überhaupt bedeutet
- 2. Die drei Overcommit-Modi im Detail
- 3. Der Zusammenhang mit dem OOM-Killer
- 4. Die Redis-Warnung im Detail verstehen
- 5. Empfehlung für Datenbank- und Cache-Server
- 6. OOM-Score-Tuning als Ergänzung zu Overcommit
- 7. Overcommit-Zustand laufend überwachen
- 8. Typische Fallstricke beim Overcommit-Tuning
- 9. Checkliste für den produktiven Einsatz
- 10. Zusammenfassung
- 11. FAQ
1. Was Speicherüberbuchung überhaupt bedeutet
Wenn ein Prozess Speicher über malloc anfordert, reserviert der Kernel dabei zunächst nur virtuellen Adressraum, nicht zwingend physischen Speicher. Erst beim tatsächlichen Schreibzugriff auf eine Speicherseite wird über einen Seitenfehler physischer Speicher zugewiesen, ein Mechanismus, der als Lazy Allocation bezeichnet wird und die Grundlage für Speicherüberbuchung bildet.
Overcommit bedeutet, dass der Kernel mehr virtuellen Speicher zusagen kann, als physisch zusammen mit dem konfigurierten Swap tatsächlich vorhanden ist, in der Annahme, dass die meisten Prozesse ohnehin nie ihren gesamten angeforderten Speicher vollständig beschreiben. Viele Programme, darunter auch PHP-FPM und die JVM einiger Elasticsearch-Setups, reservieren großzügige virtuelle Speicherbereiche im Voraus, ohne sie jemals komplett zu nutzen.
2. Die drei Overcommit-Modi im Detail
Der Kernel-Parameter vm.overcommit_memory kennt drei Werte. Modus 0, der Standardwert, aktiviert eine heuristische Prüfung: Der Kernel erlaubt die meisten Anfragen, lehnt aber offensichtlich unsinnige Anfragen ab, etwa eine einzelne Allokation, die deutlich größer als der verfügbare Adressraum wäre. Diese Heuristik ist nicht exakt dokumentiert und kann sich zwischen Kernel-Versionen leicht verändern.
Modus 1 deaktiviert jede Prüfung vollständig und erlaubt praktisch unbegrenzte Überbuchung. Das ist genau das, was Redis für zuverlässige Hintergrund-Speicherabbilder über fork() benötigt, weil der Kindprozess beim Forken zunächst denselben virtuellen Adressraum wie der Elternprozess referenziert, ohne dass sofort zusätzlicher physischer Speicher gebraucht wird. Modus 2 dagegen begrenzt die Gesamtzusage strikt auf Swap plus einen konfigurierbaren Anteil des physischen RAM über vm.overcommit_ratio oder vm.overcommit_kbytes, und lehnt Allokationen jenseits dieser Grenze mit einem Fehler ab, statt sie später scheitern zu lassen.
# Aktuellen Overcommit-Modus anzeigen
cat /proc/sys/vm/overcommit_memory
# Modus 1 (Redis-Empfehlung) temporaer setzen
sysctl -w vm.overcommit_memory=1
# Für Modus 2: zulaessiger Anteil des physischen RAM in Prozent
cat /proc/sys/vm/overcommit_ratio
3. Der Zusammenhang mit dem OOM-Killer
In Modus 0 und 1 kann der Kernel deutlich mehr Speicher zusagen, als tatsächlich physisch verfügbar ist. Versuchen viele Prozesse gleichzeitig, ihren zugesagten Speicher tatsächlich vollständig zu beschreiben, gerät das System in eine Situation, in der weder physischer Speicher noch Swap ausreichen, um alle Seitenfehler zu bedienen. Genau dann greift der OOM-Killer ein und beendet einen Prozess, um Speicher freizugeben.
Modus 2 verschiebt dieses Risiko: Statt dass eine Allokation zunächst erfolgreich erscheint und der Prozess später vom OOM-Killer beendet wird, schlägt die Allokation selbst sofort mit einem Fehler fehl, sobald die konfigurierte Obergrenze überschritten würde. Anwendungen, die Allokationsfehler sauber behandeln, profitieren davon, PHP-FPM und die meisten Datenbanksysteme sind darauf allerdings nicht in jedem Codepfad vorbereitet und reagieren auf einen fehlgeschlagenen malloc-Aufruf oft ebenfalls mit einem Absturz.
4. Die Redis-Warnung im Detail verstehen
Redis verwendet für persistente Hintergrund-Speicherabbilder, sowohl für RDB-Snapshots als auch für die AOF-Kompaktierung, standardmäßig fork(), um einen Kindprozess zu erzeugen, der den Datenbestand zum Zeitpunkt des Forks einfriert und in Ruhe wegschreibt. Der Elternprozess läuft währenddessen unverändert weiter und bedient neue Schreibzugriffe über Copy-on-Write, das heißt Speicherseiten werden erst bei tatsächlicher Änderung dupliziert.
In Modus 0 kann der Kernel diesen Fork ablehnen, wenn er heuristisch entscheidet, dass für den vollständigen virtuellen Adressraum des Kindprozesses nicht genug Speicher zugesagt werden kann, selbst wenn durch Copy-on-Write in der Praxis kaum zusätzlicher physischer Speicher benötigt würde. Redis meldet diese potenzielle Gefahr proaktiv beim Start, weshalb die offizielle Redis-Dokumentation für Produktionssysteme explizit Modus 1 empfiehlt.
# Typische Redis-Warnung im Log
# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.
# Dauerhaft auf Modus 1 setzen
echo "vm.overcommit_memory = 1" >> /etc/sysctl.d/99-redis-overcommit.conf
sysctl --system
5. Empfehlung für Datenbank- und Cache-Server
Für dedizierte Redis-Hosts, egal ob als Session-Storage oder Cache-Backend für Magento, ist Modus 1 die klare, von Upstream empfohlene Wahl, weil er Fork-basierte Persistenz zuverlässig ermöglicht, ohne dass der Kernel dabei eingreift. Das Risiko, dass die Speicherüberbuchung tatsächlich ausgenutzt wird und der OOM-Killer eingreifen muss, lässt sich durch großzügig dimensionierten RAM und konsequentes Speicher-Monitoring auf ein akzeptables Maß reduzieren.
Für MySQL- beziehungsweise MariaDB-Server, die typischerweise mit einem fest konfigurierten innodb_buffer_pool_size arbeiten und selten forken, ist Overcommit weniger kritisch, hier reicht meist der heuristische Standardmodus 0 aus. Elasticsearch-Server mit ihrer JVM-Heap-Reservierung profitieren ebenfalls kaum von Modus 1, weil die JVM ihren Heap in der Regel beim Start vollständig committet, statt lazy zu allozieren.
In gemischten Umgebungen, in denen ein Host sowohl Redis als auch andere speicherintensive Dienste betreibt, sollte Modus 1 systemweit gesetzt werden, sofern Redis läuft, kombiniert mit striktem Speicher-Monitoring über vm.min_free_kbytes und aktivem OOM-Score-Tuning für weniger kritische Prozesse, um im Ernstfall die richtigen Prozesse zuerst zu beenden.
6. OOM-Score-Tuning als Ergänzung zu Overcommit
Unabhängig vom gewählten Overcommit-Modus lohnt es sich, die OOM-Priorität kritischer Prozesse gezielt zu steuern. Über /proc/<pid>/oom_score_adj lässt sich ein Wert zwischen minus eintausend und eintausend setzen, wobei niedrigere Werte einen Prozess vor dem OOM-Killer schützen und höhere Werte ihn zu einem bevorzugten Ziel machen.
Für einen Redis-Prozess, der als zentraler Cache für mehrere Magento-Instanzen dient, ist ein negativer oom_score_adj sinnvoll, damit im Ernstfall eher ein unwichtigerer Hintergrundprozess beendet wird als der Cache selbst. Diese Feinsteuerung ersetzt keine ausreichende RAM-Dimensionierung, reduziert aber das Risiko, dass der OOM-Killer den falschen Prozess trifft.
# Redis-Prozess vor dem OOM-Killer bevorzugt schuetzen
REDIS_PID=$(pgrep -x redis-server | head -n1)
echo -500 > /proc/${REDIS_PID}/oom_score_adj
# Aktuellen effektiven OOM-Score pruefen
cat /proc/${REDIS_PID}/oom_score
7. Overcommit-Zustand laufend überwachen
Der aktuelle Grad der Überbuchung lässt sich über /proc/meminfo ablesen: CommitLimit zeigt die theoretische Obergrenze für zugesagten Speicher, Committed_AS die Summe der bereits zugesagten Allokationen aller Prozesse. Übersteigt Committed_AS den physisch verfügbaren Speicher deutlich, lohnt sich ein genauerer Blick auf die tatsächliche Speichernutzung, bevor es zu einem OOM-Ereignis kommt.
Für ein dauerhaftes Monitoring bietet sich ein einfacher Cron-Check an, der beide Werte regelmäßig protokolliert und bei einem kritischen Verhältnis alarmiert, kombiniert mit dem Systemlog auf OOM-Killer-Ereignisse, die sich über dmesg oder das Kernel-Log identifizieren lassen.
# Commit-Limit und aktuell zugesagten Speicher anzeigen
grep -E "CommitLimit|Committed_AS" /proc/meminfo
# Vergangene OOM-Killer-Ereignisse im Kernel-Log suchen
dmesg -T | grep -i "out of memory"
8. Typische Fallstricke beim Overcommit-Tuning
Ein häufiger Fehler ist, Modus 1 blind auf jedem Server zu setzen, weil eine Redis-Warnung das nahelegt, ohne zu berücksichtigen, dass andere Dienste auf demselben Host dadurch ebenfalls stärker überbucht werden können. Auf gemeinsam genutzten Hosts mit mehreren speicherintensiven Diensten sollte die Entscheidung immer host-spezifisch getroffen werden, nicht pauschal aus einer Blog-Empfehlung übernommen.
Ein weiterer Fallstrick ist, die Einstellung nur temporär mit sysctl -w zu setzen und zu vergessen, sie dauerhaft in /etc/sysctl.d/ zu persistieren. Nach dem nächsten Reboot springt der Wert dann unbemerkt zurück auf den Standardmodus 0, und die Redis-Warnung taucht beim nächsten Neustart des Dienstes erneut auf, meist zum ungünstigsten Zeitpunkt.
9. Checkliste für den produktiven Einsatz
Vor der Umstellung eines Servers sollte zunächst geprüft werden, welche Dienste tatsächlich auf dem Host laufen und ob einer davon aktiv forkt, wie es bei Redis der Fall ist. Nur wenn ein fork-lastiger Dienst vorhanden ist, rechtfertigt sich der pauschale Wechsel auf Modus 1, andernfalls bleibt der heuristische Standardmodus 0 meist die konservativere und ebenso funktionierende Wahl.
Nach jeder Änderung an vm.overcommit_memory gehört ein Neustart des betroffenen Dienstes zur Kontrolle dazu, um zu bestätigen, dass die ursprüngliche Warnung tatsächlich verschwunden ist. Zusätzlich sollte die Einstellung in die Server-Dokumentation oder das Konfigurationsmanagement, etwa Ansible oder ein einfaches Provisioning-Skript, aufgenommen werden, damit sie bei einer Neuinstallation nicht erneut vergessen wird.
Abschließend gehört ein regelmäßiger Blick auf Committed_AS im Verhältnis zu CommitLimit zum produktiven Monitoring, unabhängig vom gewählten Modus, weil ein dauerhaft nahe an der Grenze liegendes Verhältnis ein Vorbote für zukünftige Speicherengpässe ist, lange bevor der OOM-Killer tatsächlich eingreifen muss.
# Kurzer Check-Befehl für die Server-Dokumentation
echo "Overcommit-Modus: $(cat /proc/sys/vm/overcommit_memory)"
grep -E "CommitLimit|Committed_AS" /proc/meminfo
| Modus | Verhalten | Typischer Einsatz | Risiko |
|---|---|---|---|
| 0 (heuristic) | Heuristische Prüfung, lehnt offensichtlich unsinnige Anfragen ab | Standard-Server ohne Fork-lastige Workloads | Redis-Fork kann in Grenzfällen abgelehnt werden |
| 1 (always) | Keine Prüfung, praktisch unbegrenzte Überbuchung | Redis-/Cache-Server mit Fork-basierter Persistenz | OOM-Killer muss im Ernstfall eingreifen |
| 2 (never) | Strikte Obergrenze aus Swap plus Anteil des RAM | Systeme mit vorhersehbarem, festem Speicherbedarf | Allokationen können hart fehlschlagen |
| Kombination mit oom_score_adj | Kritische Prozesse gezielt vor OOM-Killer schützen | Gemischte Hosts mit mehreren Diensten | Erfordert manuelle Pflege pro Prozess |
Mironsoft
Server-Administration, Docker-Hosts und Performance-Tuning
Linux-Server, die niemand im Team richtig versteht?
Wir übernehmen Setup, Absicherung und Performance-Tuning von Linux-Servern und Docker-Hosts für Magento-Deployments, dokumentiert und nachvollziehbar statt gewachsen und unklar.
Server-Audit
Bestehende Server-Konfiguration auf Sicherheitslücken und Performance-Bremsen prüfen.
Docker-Host-Setup
Produktionsreife Docker-Umgebungen für Magento sauber aufsetzen und absichern.
Monitoring & Tuning
Ressourcenverbrauch messen und Systemd, Kernel und Dienste gezielt optimieren.
10. Zusammenfassung
vm.overcommit_memory
Zielgruppe
Admins von Redis-/Datenbank-Servern mit Overcommit-Warnungen
Kernparameter
vm.overcommit_memory (0, 1 oder 2)
Redis-Empfehlung
Modus 1, dauerhaft über /etc/sysctl.d/ gesetzt
Größter Fallstrick
Nur temporär mit sysctl -w setzen statt dauerhaft persistieren