MongoDB wird beendet, wenn der Speicher knapp wird

10

Ich habe die folgende Konfiguration:

  • Ein Host-Computer, auf dem drei Docker-Container ausgeführt werden:
    • MongoDB
    • Redis
    • Ein Programm, das die beiden vorherigen Container zum Speichern von Daten verwendet

Sowohl Redis als auch MongoDB werden zum Speichern großer Datenmengen verwendet. Ich weiß, dass Redis alle Daten im RAM behalten muss, und ich bin damit einverstanden. Leider nimmt Mongo viel RAM ein und sobald der Host-RAM voll ist (wir sprechen hier von 32 GB), stürzt entweder Mongo oder Redis ab.

Ich habe die folgenden vorherigen Fragen dazu gelesen:

  1. Beschränken Sie die MongoDB-RAM-Nutzung : Anscheinend wird der größte Teil des RAM vom WiredTiger-Cache belegt
  2. MongoDB-Speicherbegrenzung : Hier waren anscheinend Protokolldaten das Problem
  3. Begrenzen Sie die RAM-Speichernutzung in MongoDB : Hier wird vorgeschlagen, den Speicher von Mongo so zu begrenzen, dass weniger Speicher für Cache / Protokolle / Daten verwendet wird
  4. MongoDB verwendet zu viel Speicher : Hier heißt es, dass es sich um ein WiredTiger-Caching-System handelt, das tendenziell so viel RAM wie möglich verwendet, um einen schnelleren Zugriff zu ermöglichen. Sie geben auch anit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Gibt es eine Option zur Begrenzung der Mongodb-Speichernutzung? : wieder zwischenspeichern, fügen sie auch hinzuMongoDB uses the LRU (Least Recently Used) cache algorithm to determine which "pages" to release, you will find some more information in these two questions
  6. MongoDB-Index / RAM-Beziehung : Zitat:MongoDB keeps what it can of the indexes in RAM. They'll be swaped out on an LRU basis. You'll often see documentation that suggests you should keep your "working set" in memory: if the portions of index you're actually accessing fit in memory, you'll be fine.
  7. Wie kann ich das von MongoDB verwendete Caching freigeben? : gleiche Antwort wie in 5.

Was ich aus all diesen Antworten zu verstehen scheine, ist Folgendes:

  1. Für einen schnelleren Zugriff ist es für Mongo besser, alle Indizes in den RAM zu passen. In meinem Fall kann ich jedoch Indizes verwenden, die sich teilweise auf der Festplatte befinden, da ich eine recht schnelle SSD habe.
  2. RAM wird hauptsächlich zum Zwischenspeichern durch Mongo verwendet.

In Anbetracht dessen hatte ich erwartet, dass Mongo versuchen würde, so viel RAM-Speicherplatz wie möglich zu nutzen, aber auch mit wenig RAM-Speicherplatz funktionieren und die meisten Dinge von der Festplatte abrufen kann. Ich habe jedoch den Speicher des Mongo Docker-Containers (zum Beispiel auf 8 GB) begrenzt, indem ich --memoryund verwendet habe --memory-swap. Statt jedoch Daten von der Festplatte abzurufen, stürzte Mongo einfach ab, sobald der Speicher knapp wurde.

Wie kann ich Mongo zwingen, nur den verfügbaren Speicher zu verwenden und alles von der Festplatte abzurufen, was nicht in den Speicher passt?

Simone Bronzini
quelle
Es heißt OOM Killer. MongoDB kann auf Standardhardware ausgeführt werden. Ich würde es niemals mit künstlich begrenzten Ressourcen betreiben. Wenn Sie nur eine kleine Datenbank haben, ist MongoDB nicht die ideale Wahl. Wenn Sie über eine große Datenbank verfügen (dreistellige Millionen bis Milliarden Einträge), ist die Begrenzung der Ressourcen eine schlechte Wahl. Gemäß Ihrem Problem: Sie können den Kuchen nicht haben und ihn essen. Wählen.
Markus W Mahlberg
Bei korrekter Konfiguration sollte MongoDB nicht abstürzen, wenn nicht genügend Speicher vorhanden ist. Können Sie die spezifische Version des von Ihnen verwendeten MongoDB-Servers und Betriebssystems bestätigen und den Absturz detaillierter beschreiben? Gibt es beispielsweise Meldungen im MongoDB-Protokoll, dmesgdie mit dem unerwarteten Herunterfahren zusammenhängen? Die wahrscheinlichste Möglichkeit bei Docker besteht darin, dass Prozesse im Container den insgesamt verfügbaren RAM und nicht das Containerlimit erkennen.
Stennie
Gemäß den MongoDB Production Notes : Wenn Sie laufen mongodin einem Behälter ( lxc, cgroups, Dockarbeiter, etc.) , die sich nicht haben Zugriff auf alle verfügbaren RAM in einem System, müssen Sie storage.wiredTiger.engineConfig.cacheSizeGBauf einen Wert kleiner als die Menge an RAM in der Kontainer. Die genaue Menge hängt von den anderen Prozessen ab, die im Container ausgeführt werden, sollte jedoch normalerweise nicht über dem Standardwert von 50% des Arbeitsspeichers minus 1 GB liegen.
Stennie

Antworten:

9

Gemäß MongoDB BOL hier geändert in Version 3.4: Werte können von 256MBbis reichen 10TBund können a sein float. Außerdem hat sich der Standardwert geändert.

Ab 3.4dem internen Cache von WiredTiger wird standardmäßig der größere von beiden verwendet:

50% of RAM minus 1 GB, or
256 MB.

Mit WiredTigernutzt MongoDB sowohl den WiredTiger internal cache als auch den filesystem cache.

Über die verwendet filesystem cacheMongoDB automatisch den gesamten freien Speicher, der nicht von den WiredTiger cacheoder anderen Prozessen verwendet wird.

Der storage.wiredTiger.engineConfig.cacheSizeGB begrenzt die Größe des WiredTigerinternen Caches. Das Betriebssystem verwendet den verfügbaren freien Speicher für den Dateisystem-Cache, sodass die komprimierten MongoDB-Datendateien im Speicher bleiben können. Darüber hinaus wird der operating systemfreie RAM zum Puffern von Dateisystemblöcken und des Dateisystem-Cache verwendet.

Um den zusätzlichen RAM- Verbrauchern gerecht zu werden , müssen Sie möglicherweise die WiredTigerinterne Cache-Größe verringern .

Weitere Informationen zu den Optionen für die WiredTiger Storage Engine und die Konfigurationsdatei

Md Haidar Ali Khan
quelle
4

Wenn Sie genau hinschauen, ist es nicht Mongod, der für "Out-of-Memory" stirbt, sondern der Kernel-OOM-Manager (Out of Memory), der Mongod tötet, weil er die größte Speichernutzung hat.

Ja, Sie können versuchen, das Problem mit dem Monngodb-Konfigurationsparameter cacheSizeGB zu lösen. In der Containerumgebung ist es jedoch besser, cgroups zu verwenden, um die Ressourcen zu begrenzen, die einer Ihrer drei Container erhält.

JJussi
quelle