web-dev-qa-db-fra.com

À quel niveau MongoDB se verrouille-t-il sur les écritures? (ou: qu'est-ce que cela veut dire par "par connexion"

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?

58
nicksahler

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.

37
Sammaye

Le verrouillage MongoDB est différent

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 des lecteurs-écrivains

Le verrou est multi-lecteur, un seul auteur et est écrivain-gourmand. Cela signifie que:

  • Il peut y avoir un nombre illimité de lecteurs simultanés sur une base de données
  • Il ne peut y avoir qu'un seul auteur à la fois sur une collection dans une base de données (plus à ce sujet dans un instant)
  • Les écrivains bloquent les lecteurs
  • Par "écrivain-gourmand", je veux dire qu'une fois une demande d'écriture reçue, tous les lecteurs sont bloqués jusqu'à la fin de l'écriture (plus de détails à ce sujet plus tard)

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.

Atomic Document Updates

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.

Writer-Greedy

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

  • Tous les lecteurs suivants ayant besoin de ce verrou bloquent
  • Cet écrivain attendra que tous les lecteurs actuels soient terminés
  • L’écrivain va acquérir le verrou d’écriture, faire son travail, puis relâche le verrou d’écriture
  • Tous les lecteurs en file d'attente vont maintenant procéder

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'.

Questions spécifiques

Concernant les questions spécifiques:

  • Les verrous (en fait, les verrous) ne sont conservés par le noyau MongoDB que le temps nécessaire à la mise à jour d'un seul document
  • Si vous avez plusieurs connexions entrant dans MongoDB et que chacune d’elles exécute une série d’écritures, le verrou sera conservé base par base de données aussi longtemps que nécessaire pour que cette écriture soit complète.
  • Plusieurs connexions venant en écriture (update/insert/delete) seront toutes entrelacées

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.

239
William Z

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:

  1. MMAPv1 : moteur de stockage par défaut et celui utilisé dans les versions précédentes. Livré avec verrouillage au niveau de la collection.
  2. WiredTiger : le nouveau moteur de stockage, fourni avec le verrouillage et la compression au niveau du document. (Disponible uniquement pour la version 64 bits)

Notes de version de MongoDB 3.

WiredTiger

20
Londo

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.

concurrence au niveau du document

9
Muhammad Ali