Dieser Fehler tritt auf, weil BGSAVE fehlgeschlagen ist. Während BGSAVE erstellt Redis einen Child-Prozess, um die Daten auf der Festplatte zu speichern. Obwohl der genaue Grund für das Scheitern von BGSAVE in den Protokollen überprüft werden kann (normalerweise unter /var/log/redis/redis-server.log
auf Linux-Maschinen), scheitert BGAVE oft, weil der Fork keinen Speicher zuweisen kann. Oftmals scheitert der Fork daran, Speicher zuzuweisen (obwohl die Maschine genügend verfügbaren RAM hat), aufgrund einer konkurrierenden Optimierung durch das Betriebssystem.
Wie auf Redis FAQ zu lesen ist:
Das Hintergrundspeicherschema von Redis basiert auf der Copy-on-Write-Semantik von Fork in modernen Betriebssystemen: Redis verzweigt (erstellt einen Child-Prozess), der eine genaue Kopie des übergeordneten Prozesses ist. Der Child-Prozess schreibt die DB auf die Festplatte und beendet sich schließlich. Theoretisch sollte der Child so viel Speicher wie der Elternprozess verwenden, da er eine Kopie ist, jedoch teilen sich der Eltern- und der Child-Prozess dank der Copy-on-Write-Semantik, die in den meisten modernen Betriebssystemen implementiert ist, die gemeinsamen Speicherseiten. Eine Seite wird nur dupliziert, wenn sich diese im Child oder im Elternprozess ändert. Da theoretisch alle Seiten geändert werden können, während der Child-Prozess speichert, kann Linux im Voraus nicht wissen, wie viel Speicher der Child-Prozess benötigen wird. Deshalb schlägt der Fork fehl, sofern nicht genügend freier RAM-Speicher vorhanden ist, um tatsächlich alle Speicherseiten des Elternprozesses zu duplizieren. Daraus resultiert, dass es bei einem Redis-Datensatz von 3 GB und nur 2 GB freiem Speicher fehlschlagen wird.
Das Setzen von overcommit_memory auf 1 sagt Linux, sich zu entspannen und den Fork in einer optimistischeren Allokationsmethode durchzuführen, was tatsächlich für Redis vorteilhaft ist.
Redis benötigt nicht so viel Speicher, wie das Betriebssystem glaubt, um auf die Festplatte zu schreiben, und kann daher den Fork vorzeitig abbrechen.
Um dies zu beheben, können Sie:
Ändern Sie /etc/sysctl.conf
und fügen Sie hinzu:
vm.overcommit_memory=1
Dann starten Sie sysctl neu mit:
Auf FreeBSD:
sudo /etc/rc.d/sysctl reload
Auf Linux:
sudo sysctl -p /etc/sysctl.conf