2013-10-09 4 views
2

Après avoir démarré Mongo via mongod, j'ai exécuté une requête Mongo qui a pris secondes. Appeler db.serverStatus() sur mon "admin" db a montré Mongo ayant resident mémoire de 1 GB. Les docs expliquent que la mémoire "résidente" est la quantité de disque physique/RAM utilisée par Mongo.État du serveur Mongo - Mémoire «Résident»

Puis, j'ai réexécuté la même requête, mais il a fallu secondes. En regardant la mémoire resident cette fois, j'ai vu 5 Go.

La forte augmentation de la RAM, je crois, aide à expliquer pourquoi le temps de requête est passé de 300 à 8 secondes, mais pourquoi la mémoire résidente a-t-elle bondi si vite?

Existe-t-il un type d'étape de "réchauffement" recommandé pour préparer Mongo afin d'éviter les requêtes de 300 secondes?

Répondre

4

Il y a une raison pour que MongoDB utilise la fonctionnalité mmap du système d'exploitation. Cela signifie, au moins sur les systèmes Linux, que la gestion de la mémoire du mongodb est basée sur certaines fonctionnalités du système d'exploitation appelées fichiers mappés en mémoire. La mémoire dans les systèmes Linux est adressée à plusieurs niveaux essentiellement tout programme verra un espace d'adressage sur les systèmes 32 bits de 2 Go sur tous, sur les systèmes 64 bits 128 To. C'est un espace d'adressage virtuel qui signifie que sur 32/64 bits, cette quantité de mémoire peut être adressée avec des pages de mémoire de 4 Ko (la page est la partie de la mémoire gérée individuellement). C'est pourquoi, si vous démarrez mongoDB sur un système 32 bits, il y aura un avertissement que la base de données sur un tel système ne peut gérer que 2 Go de données. Évidemment, cet espace d'adressage virtuel est plus grand que la quantité de mémoire physique, de sorte qu'il existe un mappage entre ces adresses virtuelles et les adresses physiques. Certaines adresses virtuelles résident réellement dans la mémoire physique, donc elles sont dans la mémoire réelle, mais l'algorithme qui assure cela est du côté du noyau. Les programmes s'exécutant sur les systèmes Linux ne peuvent traiter que des adresses virtuelles. Si vous tentez d'accéder à une adresse de mémoire virtuelle qui n'est pas en mémoire physique, une erreur de page survient (vous pouvez suivre cela dans le champ info supplémentaire des commandes serverStatus). (Vous pouvez trouver une explication courte de ceci here)

Accéder à la mémoire dans le cas où l'adresse virtuelle réside dans la mémoire physique est aussi rapide que la mémoire, accéder à une adresse virtuelle qui n'a pas de physique signifie actuellement une pagination du disque à la mémoire et lire la mémoire aussi vite que les disques lus au hasard. (Cela rend différent dans votre cas)

Il y a une commande MongoDB qui vous pouvez appliquer la mise en cache d'une collection ou un indice de cette commande est la touch Si vous utilisez cette commande pour charger les données dans la mémoire avant la première requête vous obtiendrez les résultats en 8sec au premier essai. Malheureusement, vous ne pouvez pas vraiment forcer le système d'exploitation à garder toujours cela en mémoire, donc si vous avez d'autres choses en utilisant le système d'exploitation de la mémoire, ces données seront mises en page dans un certain temps.

Si vous avez assez de mémoire physique, mongoDB gardera tout les données et les index en mémoire. Ce n'est pas toujours nécessaire. Il y a une partie des données qui doivent être en mémoire pour éviter une quantité importante de pagefaults c'est le workingset. Vous pouvez vérifier la taille de l'ensemble de travail à l'aide de la commande db.runCommand({ serverStatus: 1, workingSet: 1 }).

Vous ne pouvez pas gérer la pagination tant que c'est au niveau du système d'exploitation, mais si vous avez assez de mémoire, le noyau aime généralement à garder autant de choses cachées que possible. Si le workingset s'inscrit dans la mémoire, vous êtes plus ou moins ok. Si certains documents sont rarement consultés et qu'il n'y a pas assez de mémoire pour tout conserver, ils seront quand même renvoyés.

Lorsque vous exécutez une requête, plusieurs événements peuvent se produire.Un index peut couvrir ce qui signifie qu'aucun document ne sera touché du tout, si votre requête est sélective dans une certaine notion, seule une partie de l'index sera touchée. malheureusement, il est vraiment difficile de définir la mémoire est suffisante et la seule chose que vous pouvez faire est de surveiller (la métrique de workingset est une estimation). Le symptôme de manquer de mémoire peut être identifié vérifier ce presentation. Et utilisez MMS.

+0

Merci pour cette réponse utile. Donc, Attaque, si j'ai assez de RAM dans la mémoire pour ne couvrir que les index, les fautes de page peuvent toujours se produire lors de la récupération des champs non indexés à partir des documents trouvés? –

+0

Le problème a plusieurs niveaux. Vous pouvez vérifier la taille de l'ensemble de travail je met à jour prochainement ma réponse. – attish

+0

J'ai mis à jour la partie liée à l'ensemble de travail. Je suis heureux, cela pourrait vous aider. – attish

Questions connexes