MongoDB se termine lorsqu'il manque de mémoire

11

J'ai la configuration suivante:

  • une machine hôte qui exécute trois conteneurs Docker:
    • MongoDB
    • Redis
    • Un programme utilisant les deux conteneurs précédents pour stocker des données

Redis et MongoDB sont utilisés pour stocker d'énormes quantités de données. Je sais que Redis doit conserver toutes ses données dans la RAM et je suis d'accord avec cela. Malheureusement, ce qui se passe, c'est que Mongo commence à prendre beaucoup de RAM et dès que la RAM hôte est pleine (nous parlons de 32 Go ici), Mongo ou Redis se bloque.

J'ai lu les questions précédentes suivantes à ce sujet:

  1. Limiter l'utilisation de la RAM MongoDB : apparemment, la plupart de la RAM est utilisée par le cache WiredTiger
  2. MongoDB limit memory : ici, apparemment, le problème était les données de journal
  3. Limitez l'utilisation de la mémoire RAM dans MongoDB : ici, ils suggèrent de limiter la mémoire de mongo afin qu'il utilise une plus petite quantité de mémoire pour son cache / journaux / données
  4. MongoDB utilise trop de mémoire : ici, ils disent que c'est le système de mise en cache WiredTiger qui a tendance à utiliser autant de RAM que possible pour fournir un accès plus rapide. Ils déclarent égalementit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Existe-t-il une option pour limiter l'utilisation de la mémoire mongodb? : mise en cache à nouveau, ils ajoutent égalementMongoDB 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. Relation index MongoDB / RAM : citation: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. comment libérer la mise en cache utilisée par MongoDB? : même réponse qu'en 5.

Maintenant, ce que je semble comprendre de toutes ces réponses, c'est que:

  1. Pour un accès plus rapide, il serait préférable que mongo adapte tous les indices dans la RAM. Cependant, dans mon cas, je suis d'accord avec les index résidant partiellement sur le disque car j'ai un SSD assez rapide.
  2. La RAM est principalement utilisée pour la mise en cache par mongo.

Compte tenu de cela, je m'attendais à ce que mongo essaie d'utiliser autant d'espace RAM que possible, mais puisse également fonctionner avec peu d'espace RAM et aller chercher la plupart des choses sur le disque. Cependant, j'ai limité la mémoire du conteneur mongo Docker (à 8 Go par exemple), en utilisant --memoryet --memory-swap, mais au lieu de récupérer des choses sur le disque, mongo s'est juste écrasé dès qu'il manquait de mémoire.

Comment puis-je forcer mongo à utiliser uniquement la mémoire disponible et à récupérer sur le disque tout ce qui ne tient pas en mémoire?

Simone Bronzini
la source
Il s'agit du tueur OOM. MongoDB est conçu pour fonctionner sur du matériel de base. Je ne l'aurais jamais exécuté sur des ressources artificiellement limitées. Si vous n'avez qu'une petite base de données, MongoDB n'est pas le choix idéal. Si vous avez une grande base de données (trois millions à un milliard d'entrées), limiter les ressources est un mauvais choix. Selon votre problème: vous ne pouvez pas avoir le gâteau et le manger. Choisir.
Markus W Mahlberg
S'il est correctement configuré, MongoDB ne devrait pas planter en cas de mémoire insuffisante. Pouvez-vous confirmer la version spécifique du serveur MongoDB et O / S que vous utilisez et décrire également le crash plus en détail? Par exemple, y a-t-il des messages dans le journal MongoDB ou en dmesgcorrélation avec l'arrêt inattendu? La possibilité la plus probable avec Docker est que les processus dans le conteneur détectent la RAM globale disponible plutôt que la limite du conteneur.
Stennie
Selon les notes de production MongoDB : si vous exécutez mongoddans un récipient ( lxc, cgroups, Docker, etc.) qui ne pas avoir accès à toute la RAM disponible dans un système, vous devez définir storage.wiredTiger.engineConfig.cacheSizeGBune valeur inférieure à la quantité de RAM disponible en le conteneur. Le montant exact dépend des autres processus en cours d'exécution dans le conteneur, mais ne doit généralement pas être supérieur à la valeur par défaut de 50% de RAM moins 1 Go.
Stennie

Réponses:

9

Selon MongoDB BOL ici modifié dans la version 3.4: les valeurs peuvent aller de 256MBà 10TBet peuvent être a float. De plus, la valeur par défaut a également changé.

À partir de 3.4, le cache interne de WiredTiger , par défaut, utilisera le plus grand des deux:

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

Avec WiredTiger, MongoDB utilise à la fois le WiredTiger internal cache et le filesystem cache.

Via le filesystem cache, MongoDB utilise automatiquement toute la mémoire libre qui n'est pas utilisée par WiredTiger cacheou par d'autres processus.

Le fichier storage.wiredTiger.engineConfig.cacheSizeGB limite la taille du WiredTigercache interne. Le système d'exploitation utilisera la mémoire disponible pour le cache du système de fichiers, ce qui permet aux fichiers de données MongoDB compressés de rester en mémoire. De plus, l ' operating systemutilisera toute RAM libre pour mettre en mémoire tampon les blocs du système de fichiers et le cache du système de fichiers.

Pour prendre en charge les consommateurs supplémentaires de RAM , vous devrez peut-être réduire WiredTigerla taille du cache interne.

Pour plus d'informations sur votre moteur de stockage WiredTiger et vos options de fichier de configuration

Md Haidar Ali Khan
la source
4

En fait, si vous regardez de plus près, ce n'est pas le mongod qui meurt pour "mémoire insuffisante", c'est le gestionnaire OOM (hors mémoire) du noyau qui tue le mongod, car il a la plus grande utilisation de la mémoire.

Oui, vous pouvez essayer de résoudre le problème avec le paramètre de configuration monngodb cacheSizeGB , mais dans l'environnement de conteneur, il est préférable d'utiliser des groupes de contrôle pour limiter les ressources que chacun de vos trois conteneurs obtient.

JJussi
la source