MongoDB v3 : les nouveautés
Le 3 février dernier, MongoDB a fait une annonce importante : la sortie de la version 3 de leur solution NoSQL (anciennement désignée comme version 2.8). Annoncée pour mars, la version 3 de MongoDB est très attendue.
MongoDB a souvent été attaqué pour ses performances en écriture et pour son administration complexe (ReplicaSet, Sharding, …).
Concrètement, on peut reprocher à MongoDB :
- Un lock global au niveau de la base de données lors des mises à jour.
- Pas d’auto découverte des clusters (ReplicaSet).
En particulier un lock d’écriture plus fin est demandé par les utilisateurs depuis juin 2010 : https://jira.mongodb.org/browse/SERVER-1240.
Principe des locks dans MongoDB
Chaque opération (lecture, écriture, mise à jour) demande un lock avant de commencer à accéder aux données. Il y a deux types de locks dans MongoDB :
- Lock de lecture : peut être partagé entre plusieurs opérations de lecture.
- Lock d’écriture : exclusif, ce qui veut dire qu’aucune autre opération ne peut avoir lieu (écriture ou même lecture).
On le voit, les locks d’écriture sont très pénalisants puisque l’accès à la base est interdit pendant la mise à jour d’une donnée. Les temps d’écriture sont très importants pour les performances globales.
Ils sont de l’ordre de la milliseconde pour une écriture de type safe mais de l’ordre de la centaine de milli-secondes pour un accès au journal.
Historique de la gestion des locks
Avant la version 2.2 : le lock était global au niveau de l’instance mongoDB, c’est à dire unique pour toutes les bases de données.
Après la 2.2 : le niveau de lock a été abaissé au niveau de la base de données (deux collections dans deux bases différentes ne le partagent pas).
Nouveautés
Voici la liste des nouveautés majeures de cette version 3 :
- Un nouveau moteur de stockage WiredTiger
- Lors des mises à jour un lock au niveau des collections (MMAPv1, WiredTiger) ou des documents (uniquement WiredTiger) plutôt qu’au niveau global (database).
- Compression des données stockées (WiredTiger).
- Un quorum élargi à 50 Replica Set (au lieu de 12).
- Un nouveau mécanisme d’authentification SCRAM-SHA-1 qui remplace Mongo-CR.
- Amélioration des traces (catégorisation).
- Client asynchrone (driver java v3).
- Performances accrues pour les index.
- Une nouvelle version de MMS à déployer localement (nommée Ops Manager).
- …
Pour la liste complète des nouveautés : http://docs.mongodb.org/v3.0/release-notes/3.0
Parmi la liste des nouveautés, la plus attendue est assurément le nouveau moteur de stockage.
Moteurs de stockage
Ouverture des API internes pour permettre à un éditeur de plugger son propre moteur de stockage.
Chaque implémentation doit fournir :
- Un format de stockage des données sur disque.
- Une vision mémoire de ces données.
On peut donc s’attendre à voir fleurir une multitude de moteurs de stockage à l’avenir tels que :
- Stockage mémoire (déjà au niveau expérimental),
- HDFS,
- Editeurs (RockDB, TokuMX, …)
- …
MongoDB v3 est livré avec deux moteurs de stockage :
- Une évolution du moteur de stockage historique : MMAPv1,
- Un nouveau moteur, WiredTiger : uniquement pour les versions 64 bits (plus globalement MongoDB ne supporte plus les versions 32 bits).
MMAPv1
MMAPv1 reste le moteur de stockage par défaut car selon MongoDB, le choix du moteur de stockage dépendra des cas d’utilisations.
On pourra même mixer les moteurs de stockage sur un même projet comme c’est le cas en interne pour MMS.
Principales évolutions :
- Lock d’écriture au niveau collection et non plus au niveau base de données.
- Journalisation améliorée.
Des gains sont donc à attendre pour les applications multi-collections et multi-threads.
WiredTiger
MongoDB a fait l’acquisition de la société WiredTiger en décembre 2014, finalisant un rapprochement des solutions respectives de ces deux sociétés.
Principales caractéristiques de ce moteur de stockage :
- Lock au niveau document
- Compression des données sur disque
- Compatible avec les principes de Mechanical Sympathy (logiciel développé en harmonie avec les particularités du hardware)
- Fragmentation mémoire réduite (par rapport à MMAPv1, la compaction est une tache de fond).
- Index compressé en mémoire.
Des gains sont donc à attendre pour pratiquement toutes les applications faisant majoritairement des écritures.
Les caractéristiques de WiredTiger laissent supposer de nouvelles améliorations dans les prochaines versions :
- Support de pseudo MVCC (et des transactions en général).
- Paramètres de tuning du moteur.
- Log-structured merge-tree (LSM-Tree) en complément du stockage actuel de type B+-Tree (LSM est particulièrement adapté aux insert en masse).
Différents types de compressions sont disponibles :
- none : pas de compression, performances maximale,
- snappy : par défaut, compromis performances/taux de compression,
- zlib : compression maximale au détriment des performances.
Contrairement au moteur de stockage MMAPv1, le moteur de stockage WiredTiger ne supporte pas la commande Touch. La commande Touch permet de monter en mémoire les données pour un accès plus rapide (working set). Par contre les données étant toujours consistantes, y compris en mémoire, la phase de consolidation du journal (journal recovery) n’est plus nécessaire.
De même le principe de padding factor (réservation d’espace fichier plus grand que nécessaire) n’est pas utilisé par WiredTiger.
Écriture sur disque
Il n’y a plus de mise à jour aléatoire des données dans les fichiers avec WiredTiger, la nouvelle valeur d’un document est ajoutée à la fin, les écritures sont donc séquentielles.
Pour écrire les données sur disque, WiredTiger utilise des checkpoints qui sont des points de synchronisation des données sur disque. Par défaut ils sont programmés toutes les 60 secondes ou quand le cache de données à écrire atteint 2 Go. Le processus d’écriture étant asynchrone avec les accès client, théoriquement les performances du disque n’impactent plus les écritures. On peut donc s’attendre à des performances équivalentes quel que soit le type de disque (SSD ou Spining).
Plus globalement, comparé à MMAPv1, WiredTiger consomme plus de CPU (plus de threads d’écriture, compression des données) mais moins d’I/Os.
Configuration
De nouveaux paramètres de lancement de MongoDB permettent de choisir le moteur de stockage, la taille du cache mais aussi la compression :
–storageEngine wiredTiger|MMAPv1
–wiredTigerCacheSizeGB int
–wiredTigerCollectionBlockCompressor none|snappy|zlib
–wiredTigerJournalCompressor none|snappy|zlib
Pour la liste complète des paramètres : http://docs.mongodb.org/v3.0/reference/configuration-options/#storage.wiredTiger
A noter que WiredTiger utilise deux caches :
- Un pour le moteur lui même.
- Un cache d’accès au disque.
La taille maximale des caches est définie par défaut à 50 % de la mémoire physique de la machine et 1 Go minimum.
Ce paramètre permet enfin de contrôler la taille mémoire des processus “mongod” mais apporte un paramètre supplémentaire à ajuster.
Migration :
Évidemment WiredTiger n’est pas compatible avec les autres formats de stockage.
Contrairement à MMAPv1, WiredTiger utilise un fichier par collection et un par index plutôt que des fichiers globaux.
Il existe deux méthodes de migration :
Import/Export des données
Il faut donc utiliser le format d’export de mongoDB comme format pivot pour la migration.
Pré-requis MongoDB 2.6, pour les versions antérieures, il faudra d’abord migrer vers cette version.
Créer un nouvel environnement pour les données.
Ensuite procédure classique :
- Exporter les données avec mongodump
- Import avec mongorestore
- Recréer les ReplicatSet, les Shards, …
Rolling Upgrade
On peut utiliser la possibilité de mixer les systèmes de stockage au sein d’un même Replica Set :
- Ajouter des nœuds avec le moteur de stockage WiredTiger.
- Une fois les données répliquées, arrêter progressivement les autres nœuds.
La procédure de migration n’est donc pas anodine, c’est pourquoi nous essaierons de mesurer dans un second article les gains à attendre en terme de performances.
Driver
Un nouveau driver Java (v3) est aussi en bêta pour l’instant. Outre une compatibilité avec MongoDB v3 (mais c’est déjà la cas avec le driver 2.13.0) la principale nouveauté est l’apparition d’un client asynchrone. D’autres drivers (pour d’autres langages) le proposaient déjà. Pour Java, il existait un projet : http://www.allanbank.com/mongodb-async-driver/index.html
L’asynchronisme permet une augmentation des performances tout en diminuant la charge CPU mais tous les projets/cas d’utilisation ne sont pas compatibles. Les cas typiques sont les chargements en masse sans interaction avec les utilisateurs.
L’utilisation du nouveau driver en production n’est actuellement pas recommandé par MongoDB. Globalement, les nouveaux drivers seront officiellement disponibles environ un mois après la version MongoDB v3 GA.
Ops Manager
Une nouvelle version de l’outil d’administration web (Ops Manager) qui est la version locale de MMS accompagne cette version 3 de MongoDB. L’outil a été revu, dans le but de simplifier l’administration et la supervision d’un cluster MongoDB. Cette offre est réservée à la version Entreprise de MongoDB et l’on dispose actuellement de très peu d’informations.
Conclusion
Cette version est juste un commencement pour MongoDB qui va dans les prochaines versions parfaire l’intégration du moteur WiredTiger. MongoDB a mis en place une politique sur la durée pour favoriser son adoption (il est disponible en bêta depuis la version 2.8). Les évolutions du moteur MMAPv1 laissent supposer un gain pour les applications existantes mais nécessiteront une évolution du code afin de profiter au mieux du lock au niveau collection (un thread d’accès par collection).
Le choix du moteur de stockage devrait devenir une étape obligée lors de la mise en œuvre de MongoDB.
Pour aller plus loin :
Articles de blogs :
/2013/11/19/mongodb-est-moins-rapide-et-alors/
/2014/10/31/bdx-io-mongodb-internals-la-vie-dune-ecriture-et-sa-replication/
Ippon Technologies est partenaire MongoDB : http://www.mongodb.com/partners/ippon
White paper sur les nouveautés de MongoDB V3 : https://www.mongodb.com/lp/white-paper/mongodb-3.0