MongoDB termina cuando se queda sin memoria


11

Tengo la siguiente configuración:

  • una máquina host que ejecuta tres contenedores acoplables:
    • MongoDB
    • Redis
    • Un programa que usa los dos contenedores anteriores para almacenar datos

Tanto Redis como MongoDB se utilizan para almacenar grandes cantidades de datos. Sé que Redis necesita mantener todos sus datos en RAM y estoy de acuerdo con esto. Desafortunadamente, lo que sucede es que Mongo comienza a tomar mucha RAM y tan pronto como la RAM del host está llena (estamos hablando de 32 GB aquí), Mongo o Redis se bloquean.

He leído las siguientes preguntas anteriores sobre esto:

  1. Limite el uso de RAM MongoDB : aparentemente, la mayor parte de la RAM es utilizada por la caché WiredTiger
  2. Memoria límite de MongoDB : aquí aparentemente el problema eran los datos de registro
  3. Limite el uso de memoria RAM en MongoDB : aquí sugieren limitar la memoria de mongo para que use una menor cantidad de memoria para su caché / registros / datos
  4. MongoDB usa demasiada memoria : aquí dicen que es el sistema de almacenamiento en caché WiredTiger que tiende a usar tanta RAM como sea posible para proporcionar un acceso más rápido. También declaranit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. ¿Hay alguna opción para limitar el uso de memoria mongodb? : caché de nuevo, también agreganMongoDB 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. Relación MongoDB índice / RAM : cita: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. ¿Cómo liberar el almacenamiento en caché que utiliza MongoDB? : misma respuesta que en 5.

Ahora, lo que parece entender de todas estas respuestas es que:

  1. Para un acceso más rápido, sería mejor para mongo ajustar todos los índices en la RAM. Sin embargo, en mi caso, estoy bien con índices que residen parcialmente en el disco ya que tengo un SSD bastante rápido.
  2. RAM es utilizada principalmente para el almacenamiento en caché por mongo.

Teniendo en cuenta esto, esperaba que Mongo intentara usar la mayor cantidad de espacio de RAM posible, pero también podría funcionar con poco espacio de RAM y recuperar la mayoría de las cosas del disco. Sin embargo, limité la memoria del contenedor mongo Docker (a 8GB por ejemplo), usando --memoryy --memory-swap, pero en lugar de buscar cosas del disco, mongo se bloqueó tan pronto como se quedó sin memoria.

¿Cómo puedo obligar a mongo a usar solo la memoria disponible y a buscar del disco todo lo que no cabe en la memoria?


Se llama asesino OOM. MongoDB está diseñado para ejecutarse en hardware básico. Nunca lo ejecuté en recursos artificialmente limitados. Si solo tiene una base de datos pequeña, MongoDB no es la opción ideal. Si tiene una base de datos grande (tres millones de millones de entradas) limitar los recursos es una mala elección. Según su problema: no puede tener el pastel y comérselo. Escoger.
Markus W Mahlberg

Si está configurado correctamente, MongoDB no debería bloquearse cuando no hay memoria. ¿Puede confirmar la versión específica del servidor MongoDB y O / S que está utilizando y también describir el bloqueo con más detalle? Por ejemplo, ¿hay algún mensaje en el registro de MongoDB o dmesgcorrelacionado con el apagado inesperado? La posibilidad más probable con Docker es que los procesos en el contenedor detecten la RAM total disponible en lugar del límite del contenedor.
Stennie

Según las Notas de producción MongoDB : si se ejecuta mongoden un contenedor ( lxc, cgroups, estibador, etc.) eso no tienen acceso a toda la memoria RAM disponible en el sistema, debe establecer storage.wiredTiger.engineConfig.cacheSizeGBa un valor inferior a la cantidad de RAM disponible en El contenedor. La cantidad exacta depende de los otros procesos que se ejecutan en el contenedor, pero normalmente no debería ser mayor que el valor predeterminado del 50% de RAM menos 1 GB.
Stennie

Respuestas:


9

Según MongoDB BOL aquí modificado en la versión 3.4: los valores pueden variar de 256MBa 10TBy pueden ser a float. Además, el valor predeterminado también ha cambiado.

Comenzando en 3.4, el caché interno de WiredTiger , por defecto, usará el más grande de:

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

Con WiredTiger, MongoDB utiliza tanto el WiredTiger internal cache como el filesystem cache.

A través de filesystem cache, MongoDB usa automáticamente toda la memoria libre que no es utilizada por WiredTiger cacheo por otros procesos.

El storage.wiredTiger.engineConfig.cacheSizeGB limita el tamaño de la WiredTigermemoria caché interna. El sistema operativo utilizará la memoria libre disponible para el caché del sistema de archivos, lo que permite que los archivos de datos comprimidos de MongoDB permanezcan en la memoria. Además, operating systemutilizará cualquier RAM libre para almacenar los bloques del sistema de archivos y el caché del sistema de archivos.

Para acomodar a los consumidores adicionales de RAM , es posible que deba disminuir WiredTigerel tamaño de la memoria caché interna.

Para obtener más información sobre su motor de almacenamiento WiredTiger y las opciones del archivo de configuración


4

En realidad, si se mira de cerca, no es mongod el que muere por "falta de memoria", es el administrador de kernel OOM (sin memoria) que mata a mongod, porque tiene el mayor uso de memoria.

Sí, puede intentar resolver el problema con el parámetro de configuración monngodb cacheSizeGB , pero en el entorno del contenedor, es mejor usar cgroups para limitar los recursos que obtiene cualquiera de sus tres contenedores.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.