Dans la documentation de mongodb, il est écrit:
À compter de la version 2.2, MongoDB implémente des verrous par base de données pour la plupart des opérations de lecture et d'écriture. Certaines opérations globales, généralement des opérations de courte durée impliquant plusieurs bases de données, nécessitent toujours un verrou global "d'instance". Avant la version 2.2, il n'y avait qu'un seul verrou "global" par instance de mongod.
Est-ce que cela signifie que dans la situation où j'ai, disons, 3 connexions à mongodb: // localhost/test à partir de différentes applications s'exécutant sur le réseau - une seule peut écrire à la fois? Ou est-ce juste par connexion?
IOW: Est-ce par connexion ou la base de données entière/test est-elle verrouillée pendant qu'elle écrit?
Ce n'est pas par connexion, mais par mongod
. En d'autres termes, le verrou existera pour toutes les connexions à la base de données test
sur ce serveur.
C'est aussi un verrou en lecture/écriture, donc si une écriture est en cours, alors une lecture doit attendre, sinon comment MongoDB peut-il savoir qu'il s'agit d'une lecture cohérente?
Cependant, je devrais mentionner que les verrous MongoDB sont très différents des verrous SQL/transactionnels normaux que vous obtenez et que normalement, un verrou sera maintenu pendant environ une microseconde entre les mises à jour moyennes.
Le verrouillage dans MongoDB ne fonctionne pas de la même manière que dans un SGBDR. Il convient donc de donner quelques explications. Dans les versions précédentes de MongoDB, il n'y avait qu'un seul verrou de lecteur/graveur global. À partir de MongoDB 2.2, il existe un verrou lecteur/graveur pour chaque base de données.
Le verrou est multi-lecteur, un seul auteur et est écrivain-gourmand. Cela signifie que:
Notez que j'appelle cela un "verrou" plutôt qu'un "verrou". En effet, il est léger et, dans un schéma correctement conçu, le verrouillage en écriture est maintenu de l’ordre d’une douzaine de microsecondes. Voir ici pour plus d'informations sur le verrouillage lecteurs-écrivains.
Dans MongoDB, vous pouvez exécuter autant de requêtes simultanées que vous le souhaitez: tant que les données pertinentes sont dans RAM), elles seront toutes satisfaites sans conflit de verrouillage.
Rappelez-vous que dans MongoDB, le niveau de transaction est un document unique. Toutes les mises à jour d'un seul document sont atomiques. Pour ce faire, MongoDB maintient le verrou d'écriture pendant le temps nécessaire à la mise à jour d'un seul document dans la RAM. Si une opération est lente (en particulier, si un document ou une entrée d'index doit être importé depuis le disque), cette opération donnera un résultat le verrou d'écriture. Lorsque l'opération fournit le verrou, la prochaine opération en file d'attente peut se poursuivre.
Cela signifie que les écritures dans tous les documents d'une même base de données sont sérialisées. Cela peut poser problème si la conception de votre schéma est médiocre et que vos écritures durent longtemps, mais dans un schéma correctement conçu, le verrouillage n’est pas un problème.
Quelques mots de plus sur le fait d'être avide d'écrivain:
Un seul auteur peut tenir le verrou à la fois; plusieurs lecteurs peuvent tenir le verrou à la fois. Dans une implémentation naïve, les auteurs pourraient mourir de faim indéfiniment s’il n’y avait qu’un seul lecteur en opération. Pour éviter cela, dans l'implémentation MongoDB, une fois qu'un seul thread fait une demande d'écriture pour un verrou particulier
Le comportement réel est complexe, car ce comportement avide d'écrivain interagit avec le rendement d'une manière qui peut ne pas être évidente. Rappelez-vous que, à partir de la version 2.2, il existe un verrou séparé pour chaque base de données; que écrit dans n’importe quelle collection de la base de données 'B'.
Concernant les questions spécifiques:
Bien que cela semble être un gros problème de performances, dans la pratique, cela ne ralentit pas les choses. Avec un schéma correctement conçu et une charge de travail typique, MongoDB saturera la capacité d'E/S du disque, même pour un disque SSD, avant que le pourcentage de verrouillage sur une base de données ne dépasse 50%.
Le cluster MongoDB dont la capacité est la plus élevée dont je suis au courant effectue actuellement 2 millions d'écritures par seconde.
Mongo 3.0 prend désormais en charge le verrouillage au niveau de la collection.
De plus, Mongo a maintenant créé une API permettant de créer un moteur de stockage. Mongo 3.0 est livré avec 2 moteurs de stockage:
Je sais que la question est assez ancienne, mais certaines personnes restent confuses ....
À compter de MongoDB 3.0, le moteur de stockage WiredTiger (qui utilise la simultanéité au niveau du document ) est disponible dans les versions 64 bits.
WiredTiger utilise un contrôle de simultanéité au niveau du document pour les opérations d'écriture. En conséquence, plusieurs clients peuvent modifier différents documents d'une collection en même temps.
Pour la plupart des opérations de lecture et d'écriture, WiredTiger utilise un contrôle de concurrence optimiste. WiredTiger utilise uniquement des verrous d'intention aux niveaux global, base de données et collection. Lorsque le moteur de stockage détecte des conflits entre deux opérations, un conflit d’écriture se produit, ce qui oblige MongoDB à réessayer de manière transparente cette opération.
Certaines opérations globales, généralement des opérations de courte durée impliquant plusieurs bases de données, nécessitent toujours un verrou global "au niveau de l'instance". Certaines autres opérations, telles que la suppression d'une collection, nécessitent toujours un verrou exclusif de la base de données.