FastConnect Inside : le vendredi du connaisseur

Pour notre session de juillet du « Vendredi du connaisseur » (session technique où chacun parle d’un sujet/problématique qu’il a rencontré pendant le mois), nous avons choisi de faire simple : pizza pour tous & prez en freestyle.

Finalement au menu, nous avons eu droit à :

  • une introduction résumée de la formation MongoDB que Mael & Florian ont suivie le mois dernier dans les locaux de FastConnect à Issy (en partenariat avec 10gen)
  • une petite présentation sur la gestion de la mémoire par la JVM et le pourquoi du classique « java.lang.OutOfMemoryError: PermGen space » par Arnaud
  • un survol sur le fonctionnement du SSO & intégration CAS accompagné d’une démo qui marche :) par Marc

Sans oublier les 6 pizzas (de 2 personnes) : Ananas, Cap Horn, Bolognaise, Catalane, Los Angeles et Orientale ;)

Rendez vous à la prochaine session …

Équipe FastConnect Rennes

Paris JUG Juillet 2012 – Couchbase

Mardi 3 Juillet s’est déroulé le Paris JUG. Cette session était orientée 100% NoSQL.

La première partie fut animée par Raghavan « Rags » N. Srinivas sur une présentation de Couchbase.


Attention : on parle bien de Couchbase, pas de CouchDB !
Je reviendrai sur la différence entre les deux dans quelques lignes…

Avant de parler de Couchbase, Rags nous explique l’intérêt du NoSQL, comme la scalabilité horizontale et donc un coût maitrisé.
Si vous n’êtes pas encore convaincu, je vous suggère de voir leur document « Why NoSQL ? » sur le site de Couchbase : http://www.couchbase.com/why-nosql/nosql-database

Qu’est-ce que Couchbase ?

Maintenant se pose la grande question : qu’est-ce que Couchbase ?
La réponse courte : C’est une base NoSQL, orienté « clé/valeur » mais avec des fonctionnalités orientées « document ».

Avant Couchbase, il y avait Membase : un Memcached survitaminé, avec réplication des caches, persistances, une interface d’admin Web bien sympa, etc.
Membase n’existe plus, Couchbase le remplace et l’intègre.

On peut donc utiliser Couchbase comme un cache mémoire pure, en mode clé/valeur, avec l’API cliente de Memcached.

Mais alors, quel est le rapport entre Couchbase et CouchDB ?
Couchbase intègre CouchDB !
Pour prendre un exemple simple : quand vous sauvegardez un document JSON, ce dernier va être envoyé dans le cache Memcached, puis persisté sur disque avec le moteur de CouchDB (de manière asynchrone).

On peut comparer le processus avec celui de MongoDB, à la différence que MongoDB ne possède pas son module de Caching, mais délègue cette gestion à l’OS à l’aide de « Memory-mapped files », qui va flusher sur disque de temps en temps.

Pour mieux illustrer mes propos, voici l’écran de monitoring lorsque je fais une écriture massive :

On remarque un pique de « ops per second » : ce sont mes écritures massives
Mais la donnée se trouve seulement en mémoire, pas encore sur le disque !
On voit alors que le « disk write queue » augmente d’un coup : c’est la file d’attente avant persistance sur disque.
Quelques secondes plus tard, on voit que cette dernière diminue petit à petit.
En même temps, on voit que la base augmente sur le disque dans « couch disk/data size ».
Et toujours en même temps, on voit des « creates per sec » pendant cette phase de persistance.

Pour comprendre comment fonctionne Couchbase, et comment il intègre CouchDB, vous pouvez lire ceci : http://www.couchbase.com/couchdb

Comment lire/écrite dans Couchbase (en Java) ?

Couchbase est donc très orienté performance, puisqu’on va exploiter au mieux la mémoire.
De plus, les opérations de l’API sont de type « fire and forget » : quand on demande de sauvegarder un document, l’API nous rend la main tout de suite sans savoir si la sauvegarde a bien fonctionné !
Pour cela, il va y avoir un mécanisme semblable aux « Future » en Java, ou au « Write Concern » en MongoDB ou Cassandra.
L’API va donc nous renvoyer un objet « OperationFuture », sur lequel on va pouvoir, plus tard, demander d’attendre la fin de la sauvegarde.
Voici un exemple de code, plus parlant je l’espère :)

CouchbaseConnectionFactory factory = new CouchbaseConnectionFactory(
  Arrays.asList(URI.create("http://localhost:8091/pools")),
  "default",
  "");
client = new CouchbaseClient(factory);

GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();

// on stocke ici les futures des opérations d'insertion
List<OperationFuture<Boolean>> futures = new ArrayList<OperationFuture<Boolean>>();

for (int cpt = 0; cpt < 80000; cpt++) {

 // création d'un document
 People people = new People();
 people.setFirstname("Mathias");
 people.setLastname("Kluba");

 // j'utilise ici GSON pour construire mon JSON à partir de mon POJO
 String json = gson.toJson(people);

 // on va générer un ID pour chaque item
 UUID uuid = UUID.randomUUID();

 // sauvegarde de l'objet
 OperationFuture<Boolean> setResult = client.set(
 uuid.toString(),
 0,
 json);

 // on conserve le future pour plus tard...
 futures.add(setResult);
}

// maintenant qu'on a balancé les sauvegarde sur le server,
// on attend la fin de chacune d'entre elles,
// et on vérifie que la sauvegarde a réussie
for (OperationFuture<Boolean> f : futures) {
 Assertions.assertThat(f.get()).isTrue();
}

Ce qui est sympa, c’est que même la lecture peut être asynchrone : on balance plein de requête au serveur, et on demande ensuite le résultat en asynchrone à l’aide du Future.

Comme tout fonctionne en mode asynchrone, cela peut poser des problèmes lors de l’écriture : comment gérer les écritures concurrentes ?
En base relationnelle, on va vouloir faire une transaction, pour être sûr que personne ne modifie la même donnée.
Mais Couchbase ne supporte pas les transactions !
Ceci dit, il y a moyen de gérer la concurrence de manière « Optimiste » : on va admettre que tout va bien dans la plupart des cas, et s’il y a un problème de concurrence, alors on va gérer l’erreur au niveau de l’application.

Pour ça, il y a le mécanisme de CAS (Check and Set).
Le CAS va se servir d’une sorte de Checksum qui va nous permettre de vérifier si quelqu’un n’a pas modifié le même objet entre temps.
Ex :

  • Je récupère un objet avec son CAS
  • Je le modifie en mémoire
  • Quelqu’un d’autre le récupère aussi, le modifie et le sauvegarde en base
  • Lorsque je le sauvegarde, je précise la valeur du CAS que j’ai obtenu
    • ERROR : la valeur du CAS fournie n’est pas le même en base : quelqu’un a modifié le même objet entre temps : la sauvegarde échoue

Comme Linus Torvalds disait : TALK IS CHEAP. SHOW ME THE CODE !

GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();

// création d'un document
People people = new People();
people.setFirstname("Mathias");
people.setLastname("Kluba");

// j'utilise ici GSON pour construire mon JSON à partir de mon POJO
String json = gson.toJson(people);

// on va générer un ID pour chaque item
UUID uuid = UUID.randomUUID();

// sauvegarde de l'objet
OperationFuture<Boolean> future = client.set(
 uuid.toString(),
 0,
 json);

Assertions.assertThat(future.get()).isTrue();
System.out.println(future.getStatus());

// obtient l'objet avec son CAS
CASValue<Object> withCas = client.gets(uuid.toString());

people = gson.fromJson((String)withCas.getValue(), People.class);
people.setFirstname("Roi Mathias 1er");

json = gson.toJson(people);

// tente de mettre à jour l'objet avec son CAS
CASResponse response = client.cas(uuid.toString(), withCas.getCas(), people);

Assertions.assertThat(response).isEqualTo(CASResponse.OK);

// tente de mettre à jour une seconde fois:
// mais qui ne va pas marché car on n'a pas le bon CAS

response = client.cas(uuid.toString(), withCas.getCas(), people);

Assertions.assertThat(response).isEqualTo(CASResponse.EXISTS);

Un autre truc sympa, hérité de Memcached, c’est la notion de TTL (Time To Live).
Si je reprends le code de la sauvegarde, on remarque un 2 ème argument de type Integer :


// sauvegarde de l'objet
OperationFuture<Boolean> setResult = client.set(
 uuid.toString(),
 0,
 json);

C’est en fait le TTL en seconde : je peux ainsi dire « sauvegarde moi cette donnée, mais elle expire dans 60sec ».
Ici, cas particulier, je ne veux pas d’expiration, la valeur du TTL est donc 0.

Bon, faire un « set/get » en mode clé/valeur, c’est bien mais parfois ça peut être limitant…
Et si je veux maintenant requêter sur le « lastname » ?

C’est là que l’approche « orienté document » de Couchbase est intéressante :
Ils prennent pour postula que la majorité de vos requêtes seront de type « clé/valeur ».
Tout d’abord, quand vous sauvegardez une valeur au format JSON, cette valeur sera traitée de manière très spéciale par Couchbase.
Mais par défaut, on ne peut donc pas requêter sur les champs de votre JSON. Pour ce faire, il faut créer une sorte d’index sur les champs que vous avez besoin de requêter.

Je dis bien « une sorte d’index », car en Couchbase on appelle ça une « Vue » (comme les Vue SQL), mais le plus fun c’est qu’on code cette vue avec une fonction de Map-Reduce (ou Map seulement) ;)

En résumé : les Vues sont des « Map-Reduce » à la demande.

Quand on interroge une vue, on peut demander le résultat déjà calculé au préalable, ou re-indexer la base en re-exécutant la fonction de Map-Reduce.
Voici ce qui se passe si j’interroge une vue en forçant la re-indexation :

Voici un exemple de Vue et son utilisation en Java :


Query query = new Query();

query.setReduce(false);
query.setIncludeDocs(false);
query.setStale(Stale.FALSE);

View view = client.getView("people", "bylastname");

Paginator paginator = client.paginatedQuery(view, query, 500);

while (paginator.hasNext()) {
 ViewRow row = paginator.next();
 System.out.println(
  "ID: " + row.getId() +
  " Key: " + row.getKey()  +
  " Value: " + row.getValue());
}

Et voilà à quoi ça ressemble coté Couchbase :

Petit détail : si vous forcer la re-indexation, ça ne s’applique bien sûr qu’aux nouvelles données ou aux données changées… donc si vous avez déjà 80000 items, que le Map-Reduce est terminé, et que vous ajoutez 80 items, le Map-Reduce sera plus rapide :)

Pour conclure sur les aspects requêtages, Couchbase, offre une API Memcached (pour de la haute performance) mais offre aussi une API REST, beaucoup plus « Web friendly ».
Les applications Web peuvent alors récupérer le JSON avec une URL REST qui ressemble à cela :
http://localhost:8091/couchBase/default/00006e0b-4b58-465d-b045-e2a485baaa51

Pour obtenir le résultat d’une vue, cela ressemble à cela :
http://localhost:8091/couchBase/default/_design/dev_people/_view/bylastname?limit=10&skip=0

La présentation de Couchbase s’arrête à peu près là. On voit alors que Couchbase est orienté Web, Performance, Scalabilité Horizontale, et que son installation et utilisation est très simple.

Couchbase et Cluster

Mais je souhaite aller plus loin,  j’ai voulu savoir comment fonctionne les aspects « scalabilité horizontale » de Couchbase.
Premièrement : tout comme Cassandra, chaque nœud Couchbase fonctionnent de la même manière, aucun n’est spécialisé.

Couchbase utilise Memcached, donc exploite le même mécanisme de répartition de charge grâce au « Consistent Hashing » : les données sont uniformément réparties sur tous les nœuds disponibles.
Et si j’ajoute un nœud ?
Et bien il n’est pas exploité tout de suite : il est en attente de Re-Balancing.
Cette opération vous permet donc de re-balancer les données sur plusieurs nœuds à la fois, si vous en ajoutez plusieurs :

Attention : c’est une opération bloquante et elle peut prendre du temps, ce qui rend donc votre serveur indisponible. Il faut alors choisir le moment de son exécution judicieusement…. mais au moins, ce n’est pas automatique, et ça ne va pas planter votre prod lors d’une forte charge !

Le même mécanisme fonctionne quand on supprime un nœud :

Tout ça, c’est pour répartir la charge, et donc :

  • Exploiter le disque + mémoire de plusieurs machines pour accélérer les requêtes de lecture/écriture
  • Exploiter le CPU de plusieurs machines pour accélérer le Map-Reduce des Vues

Mais qu’en est-il de la résilience ?
Elle est assuré grâce à la réplication, et on configure ça au niveau d’un « Bucket ».

Un « Bucket » c’est l’équivalent d’une base en SQL.
Il n’y a pas de notion de « table » (ou « collection » comme en Mongo), si vous voulez séparer des données alors il faut créer un autre Bucket.
Ce dernier possède un quota en mémoire, et un nombre de réplica.
Si le nombre de réplica est 1, alors la donnée sera écrite sur 2 nœuds.

Conclusion

En conclusion, j’ai été agréablement surpris.
Premièrement, j’ai confondu Couchbase et CouchDB : Couchbase c’est un mixe des meilleurs choses de Memcached et CouchDB, c’est donc pas mal :)
L’approche « Vue avec Map-Reduce » est intéressante : on ne ralentit pas les écritures pour mettre à jour un index, ou construire un « b-tree », alors que finalement on va requêter sur seulement quelques champs du document…
Il y a donc de très bonnes idées, même si, à mon avis, il reste des choses à améliorer.
Couchbase est donc différent des autres solutions NoSQL, avec ses avantages et ses inconvénients.
Vous avez donc une base de données qui vient étoffer votre panel de solutions NoSQL, ce qui vous donne encore plus de choix, mais ce qui rend la tâche encore plus complexe :)

FastConnect embrasse la cause BPM

Il était naturel que FastConnect complète et élargisse son offre avec un pôle BPM.

C’est chose faite maintenant avec la création d’un pôle dédié sous la responsabilité de François Sallé, un expérimenté du domaine depuis 15 ans.

Fort de l’exemple des autres pôles qui composent FastConnect, ce silo a pour vocation à s’appuyer sur l’excellence de ses consultants, sa maîtrise reconnue des produits des éditeurs partenaires ainsi que de nouveaux partenariats.

Cette structure a pour but de croitre rapidement afin d’offrir aux clients existants et à venir toute la palette des services nécessaires à la bonne mise en œuvre d’un projet.

D’ores et déjà, l’entité est en mesure de prendre en charge tout type d’intervention autour du concept BPM, que ce soit de l’expression des processus à l’implémentation d’une solution.

N’hésitez pas à nous contacter. 

FastConnectement vôtre.

MongoDB Day Paris 2012 – 8 – MongoDB 2.2

La journée s’est conclue par un aperçu des principales fonctionnalités apportées par la version 2.2 de Mongo qui sortira dans le courant de l’été 2012.

  • Nouveau framework d’agrégation de donnée, en complément du map-reduce existant.
  • TTL collections permettant d’avoir des objets effacés automatiquement après un temps donné.
  • Meilleure concurrence, le lock se faisant maintenant au niveau d’une base de donnée au lieu de se faire sur tout un processus mongod
  • Data aware sharding permettant d’ajouter un niveau d’affinité aux données pour aider mongo à placer les chunks sur les différents shards. Particulièrement utile en environnement multi-datacenter pour faire en sorte que les données d’une région restent sur celle-ci.
  • Amélioration des optimisations de requêtes

Le détail des changements peut être trouvé ici

Ce billet fait partie de la série sur la journée MongoDB Day Paris 2012:

MongoDB Day Paris 2012 – 7 – Déploiement et Monitoring – Mathias Kluba, Fastconnect

Suite à notre partenariat avec 10gen, et notre engouement autour de MongoDB, nous avons décidé de parler de déploiement et supervision lors du passage en Prod d’un cluster MongoDB.

Cette session a été présentée par notre consultant Mathias Kluba, ainsi que Loic Dachary de eNovance, société spécialisée dans les services Cloud et l’infogérance.
eNovance, de par leur infrastructure Cloud OpenStack, ont une grande expérience autour du déploiement et du monitoring, et la demande de déploiement de cluster MongoDB augmente de jours en jours…
eNovance sont aussi très actif atour de la technologie de déploiement Puppet, et contribuent avec Puppet Labs sur le sujet.
Ça a donc été un grand honneur de pouvoir co-animer cette session avec Loic.

Cette présentation est constituée de 2 axes: le déploiement et le monitoring.

Déploiement

Le déploiement peut s’avérer complexe quand on souhaite déployer un cluster MongoDB avec ReplicatSet et Sharding…
Mais de nombreux outils supportent MongoDB grâce une communauté très active.

Voici des outils OpenSources qui peuvent vous aider à cela:

Lors de cette session, nous avons montré une démo de déploiement MongoDB sur Amazon EC2 avec Cloudify.
Là où Chef et Puppet vont déployer le nécessaire sur une machine en fonction de son rôle, Cloudify s’oriente sur le déploiement d’une application, avec tous les middlewares nécessaires, et s’assure aussi de créer les machines virtuelles si besoin.
Cette démo montre alors le déploiement d’un cluster en mode Sharding à l’aide des Recipes de Cloudify (script Groovy).
A noter que Cloudify peut déléguer le déploiement à Chef ou Puppet, et ainsi re-utiliser vos Recipes existantes.

Lors de cette démo on voit aussi la possibilité de définir des « Custom Commands » dans Cloudify, ce qui nous a permis d’exécuter un « mongodump » sur tous les nœuds du cluster à l’aide d’une seul commande (dump ensuite déposé sur Amazon S3).
Vous pouvez alors automatiser de nombreuses tâches de support par ce biais.

Monitoring

La seconde partie de la session s’oriente sur le monitoring d’un cluster MongoDB.
Si MongoDB vient avec quelques outils de monitoring, ces derniers ne seront pas suffisant en condition réel de production.

Si vous n’avez pas une infrastructure de monitoring déjà existante, et que vous ne voulez pas payer le coût d’installation/maintenance, vous avez la possibilité d’utiliser des services de Monitoring (Monitoring as a service) comme:

  • MMS: le service de monitoring de 10gen, spécialisé MongoDB, complétement gratuit et pouvant aider le support 10gen à diagnostiquer vos problèmes
  • Server Density: un service de monitoring générique mais avec une très bonne intégration MongoDB out-of-the-box.

Par contre, si vous voulez intégrer le monitoring de MongoDB à vos outils de monitoring existants, tout comme pour le déploiement, de nombreux outils OpenSources supportent MongoDB grâce à la communauté: Munin, Nagios, Cacti, etc.

Mais ces outils ont généralement une vision « machine »: vous sélectionner votre serveur, et vous avez les statistiques du nœud qui y est installé.
Cloudify gère aussi le monitoring mais du point de vue d’une application: on a l’état de santé de l’application en agrégeant les informations des différents middlewares, ou des différents nœuds du cluster MongoDB.
La session s’achève alors avec une démo de la partie monitoring de Cloudify, avec un cluster MongoDB en Sharding soumis à une charge simulée par une application JMeter.

En conclusion, on remarque que les efforts des communautés OpenSources rend possible l’automatisation des déploiements et le monitoring de MongoDB.
Mais vous pouvez aussi être acteurs dans ces communautés, il en revient donc à vous la responsabilité d’adopter ces outils, remonter les bugs existants, ou les faire évoluer, plutôt que de re-inventer des scripts de votre coté…

Vous pouvez voir la démo de déploiement et monitoring de MongoDB sur Amazon EC2 avec Cloudify sur notre chaine Youtube:

Ce billet fait partie de la série sur la journée MongoDB Day Paris 2012:

MongoDB Day Paris 2012 – 6 – The New Aggregation Framework – Ross Lawley, 10gen

Ross Lawley a présenté pour la dernière conférence de la journée le nouveau framework d’agrégation de données qui va bientôt être disponible avec la prochaine version 2.2 de Mongo.

Le but annoncé de cette nouvelle fonctionnalité est d’apporter un outil complémentaire au map-reduce. La construction de nombre de tâches simples telle que faire une somme, une moyenne ou trouver un minimum/maximum a été grandement simplifié. De plus les performances sont bien meilleures puisque tout est écrit directement en C++ ce qui évite l’overhead de la transcription du javascript utilisé par map-reduce.

Le principe est de décrire une chaîne d’opérations à appliquer, voilà un petit aperçu de la syntaxe :

  • $math : requête, équivalent du find
  • $project : met en forme les résultats, notamment en enlevant/ajoutant des champs
  • $unwind : permet de faire du streaming de tableau, chaque élément du tableau sera traité comme un document
  • $group : agrège les données
  • $sort : fonctionnalités de trie
  • $limit : limite le nombre de documents renvoyés
  • $skip : exclue certains documents du résultat

La syntaxe donne une idée des possibilités du framework, Ross a montré un bon nombre d’exemples pendant la conférence pour illustrer cela. A noter que le sharding est supporté, dans ce cas c’est le mongos qui se charge d’invoquer la chaîne d’opérations.

N’hésitez pas à consulter la documentation officielle pour plus de détails et d’exemples.

Ce billet fait partie de la série sur la journée MongoDB Day Paris 2012:

MongoDB Day Paris 2012 – 5 – How and When to Scale MongoDB with Sharding – Daniel Roberts, 10gen

Comment et quand utiliser le sharding de MongoDB pour scaler horizontalement son application? Tel était le sujet de la conférence qui était principalement dédié aux nouveaux utilisateurs découvrant le sharding.

Comme on le sait le sharding sert à scaler horizontalement l’application, cependant si c’est le débit en lecture que l’on veux augmenter alors il peut être plus judicieux d’agrandir la taille du réplica set tout en autorisant la lecture sur les secondaires, à condition d’accepter des lectures éventuellement inconsistantes.

Pour pouvoir utiliser le sharding deux composants sont nécessaires en plus des mongod. Les mongos sont le point d’entrée de la base de donnée et servent de routeur, les mongoConfig possèdent les méta-données des collections, notamment quelle donnée se trouve sur quel shard. Les données d’une collection sont découpées en chunks, lorsqu’un chunk dépasse une certaine taille il est alors coupé en deux et l’un des chunks peut alors migrer vers un nouveau shard. La migration se fait par copie, lors de la migration les données sont toujours disponibles à la lecture et à l’écriture sur le shard initial, une fois la migration finie les mongoConfig sont reconfigurés.

Si l’on décide de «sharder» une collection alors il faut faire très attention au choix de la clé de sharding. En effet le partitionnement se fait par plage de données. Cela implique que si la clé est incrémentale alors les données insérées iront toutes vers le même shard qui stocke la plage la plus élevée. Si la clé est aléatoire alors tous les shards serons mis à contribution, cela veux dire aussi que l’ensemble des index de la collection doivent être gardé en ram. On peux aussi créer une clé semi-aléatoire, par exemple une combinaison du mois et d’une fonction aléatoire, ceci afin de ne mobiliser qu’une fraction des shards.

Un cas possible de mauvais design du modèle arrive lorsqu’un document a plusieurs identités, par exemple un utilisateur possédant une adresse mail, facebook, twitter… Si l’on choisit comme clé de sharding un de ces champs, l’adresse mail par exemple, alors les requêtes basées sur les autres identités ne connaîtront pas le routage de l’objet, elles seront donc obligées de broadcaster la requête sur l’ensemble des shards ce qui peut entraîner de piètres performances. Si plusieurs de ces champs sont utilisés comme identité lors des requêtes alors il vaut parfois mieux découper l’objet en plusieurs documents : un pour chaque identité (dénormalisation). Plusieurs requêtes sont alors nécessaires pour faire la jointure mais ces requêtes aurons l’avantage d’être routées.

Un dernier conseil est de penser le design du schéma en anticipant la possible futur utilisation du sharding. Mais de n’effectuer le sharding que lorsqu’on en a vraiment besoin, lorsqu’on arrive à court de ressources matérielles. À noter que la solution peut aussi être de se passer du sharding et de scaler verticalement en ajoutant de la ram ou du disque.

Ce billet fait partie de la série sur la journée MongoDB Day Paris 2012:

MongoDB Day Paris 2012 – 4 – Journaling and the storage engine – Dan Pasette, 10gen

Cette conférence mettait en avant le système de persistance sur disque de Mongo ainsi que la journalisation mise en place pour assurer la reprise sur panne rapide et la consistance des données. Le fonctionnement interne de ces mécanismes était aussi abordé.

Dan Pasette a expliqué le système de pré-allocation agressif de Mongo qui réserve toujours un fichier en avance pour le stockage de chaque base de donnée afin de limiter la fragmentation du fichier et d’être prêt lorsque le précédent est plein. Sachant que la taille de chaque nouveau fichier alloué est le double du précédent jusqu’à atteindre la limite de 2gb, cela implique que pour une petite base de donnée une part importante de sa taille sur le disque n’est pas réellement utilisé. L’overhead sur le disque est donc important ce qui perturbe parfois les nouveaux utilisateurs.

Un autre élément qui rend parfois les utilisateurs confus est le mapping de tous les objets Mongo dans un segment de mémoire virtuelle. Il est important de comprendre qu’un segment ne correspond par forcément à de la ram, une partie de ses pages peuvent être sur disque.

Autre élément souvent méconnu : un coefficient de padding compris entre 0 et 2 existe pour chaque collection. Pour chaque nouveau document créé Mongo alloue en plus de sa taille réelle une fraction supplémentaire. Ceci permet d’éviter de devoir déplacer l’objet plus tard s’il grossit lors de l’ajout de nouvelles données. Il faut noter que ce coefficient est calculé automatiquement par Mongo ; il n’est pas configurable.

Le journal écrit par défaut toutes les 100ms sur le disque (contre 60s pour le FSYNC des collections) ou tous les 100mb d’écriture. Mais aussi chaque fois que le « write concern » l’exige, le « write conccern » étant la contrainte de durabilité exigé par le client pour les écritures. À noter que le journal est un fichier circulaire de taille fixe mais paramétrable et qu’il est recommandé pour de meilleures performances de le placer sur un disque séparé.

Ce billet fait partie de la série sur la journée MongoDB Day Paris 2012: