MongoDB est la performance sur l'agrégation des requêtes
Après avoir entendu tant de bonnes choses à propos de MongoDB rendement, nous avons décidé de donner Mongodb d'essayer de résoudre un problème que nous avons. J'ai commencé par déplacer tous les dossiers que nous avons dans plusieurs bases de données mysql à une collection unique dans mongodb. Il en est résulté une collection avec 29 Millions de documents (chacun d'entre eux ont au moins 20 champs) qui prend environ 100 GO d'espace dans la HD. Nous avons décidé de les mettre tous dans une seule collection, puisque tous les documents ont la même structure et la nous voulons de la requête et l'ensemble des résultats sur l'ensemble de ces documents.
J'ai créé quelques indices pour correspondre à mes requêtes sinon encore un simple count() prendrait des années. Toutefois, les requêtes comme distinct() et() encore prendre trop longtemps.
Exemple:
//creation of a compound index
db.collection.ensureIndex({'metadata.system':1, 'metadata.company':1})
//query to get all the combinations companies and systems
db.collection.group({key: { 'metadata.system':true, 'metadata.company':true }, reduce: function(obj,prev) {}, initial: {} });
J'ai pris un coup d'oeil à la mongod journal et il a beaucoup de lignes comme celles-ci (lors de l'exécution de la requête ci-dessus):
Thu Apr 8 14:40:05 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1048890 nreturned:417 154ms
Thu Apr 8 14:40:08 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1050205 nreturned:414 430ms
Thu Apr 8 14:40:18 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1049748 nreturned:201 130ms
Thu Apr 8 14:40:27 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1051925 nreturned:221 118ms
Thu Apr 8 14:40:30 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1053096 nreturned:250 164ms
...
Thu Apr 8 15:04:18 query database.$cmd ntoreturn:1 command reslen:4130 1475894ms
Cette requête a pris 1475894ms qui est plus long que ce que je m'attends (les résultats de la liste dispose d'environ 60 entrées). Tout d'abord, est-ce prévu, étant donné le grand nombre de documents dans ma collection? Sont l'agrégation des requêtes en général devrait être si lent dans mongodb? Des idées sur comment puis-je améliorer la performance?
Je suis en cours d'exécution mongod dans une seule machine avec un dual core et de 10 go de mémoire.
Merci.
- Bien que cette question est trop vieux et vient encore à des moteurs de recherche lorsque vous effectuez une recherche pour MongoDB agrégation cadre. Mario vous n'avez pas mentionné votre MongoDB version, parce qu'ils AF amélioré beaucoup de choses en 2.4 et je le fais sur une merde m1. EC2 avec 3,7 G de mémoire sur une collection de 69m et c'est beaucoup plus rapide qu'elle ne l'habitude d'être. Avez-vous essayé la nouvelle version ou que vous avez passé avec une approche différente? Assurez-vous il ya des tonnes de points de référence pour AF vs MapReduce, mais jetez un oeil à la dernière date de 10Gen blog.mongodb.org/post/62900213496/... tnx
- Merci pour votre commentaire. C'était en 2010, je crois que nous avons été en utilisant quelque chose comme MongoDB 1.4.0. Il a été un moment, je suis sûr que beaucoup de choses ont changé dans mongodb depuis, mais je n'ai pas travaillé sur ce projet depuis la fin de l'année 🙂
- Merci Mario pour la réponse. J'ai juste commencé à l'aide de MongoDB (environ un an) et je me demandais à voir ce qui est arrivé à votre projet. Bonne chance tout de même 🙂
Vous devez vous connecter pour publier un commentaire.
L'idée est que vous pouvez améliorer la performance de l'agrégation des requêtes à l'aide de MapReduce sur une fragmenté de la base de données est distribuée sur plusieurs machines.
J'ai fait quelques comparaisons de la performance de Mongo du Mapreduce avec un groupe par l'instruction select dans Oracle sur la même machine. Je n'ai trouver que Mongo est environ 25 fois plus lent. Cela signifie que j'ai du fragment de données sur au moins 25 machines à obtenir les mêmes performances avec Mongo comme Oracle offre sur une seule machine. J'ai utilisé une collection/table avec environ 14 millions de documents/lignes.
D'exporter les données à partir de mongo via mongoexport.exe et en utilisant les données exportées comme une table externe dans Oracle et de faire un groupe par Oracle a été beaucoup plus rapide que Mongo propre MapReduce.
Couple de choses.
1) Votre requête de groupe est en cours de traitement beaucoup de données. Alors que le jeu de résultats est petit, on dirait qu'il fait un tableau à l'échelle de toutes les données dans votre collection dans le but de générer petit résultat. C'est probablement la cause de la lenteur. Pour accélérer le processus, vous voudrez peut-être regarder à la performance de disque de votre serveur par le biais de la commande iostat tandis que la requête est en cours d'exécution, comme c'est probablement le goulot d'étranglement.
2) Comme cela a été souligné dans d'autres réponses, le groupe de commande utilise l'interpréteur javascript, ce qui va limiter les performances. Vous pouvez essayer en utilisant le nouveau cadre de l'agrégation, qui est libérée sous forme de bêta en 2.1 (note: ceci est une version instable Février 24 2012). Voir http://blog.mongodb.org/post/16015854270/operations-in-the-new-aggregation-framework pour une bonne introduction. Ce ne sera pas surmonter volume de données problème dans (1), mais il est implémenté en C++ et si javascript temps est le goulot d'étranglement, alors il devrait être beaucoup plus rapide.
3) une Autre approche serait d'utiliser des différentiels réduire la carte pour générer un deuxième collection avec vos groupes de résultats. L'idée est que vous devez exécuter un plan pour réduire le travail d'agréger vos résultats une fois, puis exécuter périodiquement une autre map-reduce travail qui re-réduit de nouvelles données dans la collection existante. Ensuite, vous pouvez interroger cette deuxième collection à partir de votre application plutôt que d'exécuter une commande de groupe de tous les temps.
Agrégation (carte de réduire ou autre) est très lent à mongo, car il est fait par le VM javascript, pas le moteur de base de données. Cela continue d'être une limitation de cette (très bonne, l'omi a) db pour les séries chronologiques de données.