Le verrouillage MongoDB est différent
Le verrouillage dans MongoDB ne fonctionne pas comme le verrouillage dans un SGBDR, donc un peu d'explication s'impose. Dans les versions antérieures de MongoDB, il y avait un seul verrou global de lecture/écriture. À partir de MongoDB 2.2, il existe un verrou de lecture/écriture pour chaque base de données.
Le verrou lecteurs-écrivain
Le verrou est à plusieurs lecteurs, à un seul écrivain et est gourmand en écriture. 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 rédacteur à la fois sur une collection dans une base de données (plus d'informations à ce sujet dans un instant)
- Les rédacteurs bloquent les lecteurs
- Par "écrivain gourmand", je veux dire qu'une fois qu'une demande d'écriture arrive, tous les lecteurs sont bloqués jusqu'à ce que l'écriture soit terminée (plus sur cela plus tard)
Notez que j'appelle cela un « loquet » plutôt qu'un « verrou ». En effet, il est léger et, dans un schéma correctement conçu, le verrou en écriture est maintenu de l'ordre d'une douzaine de microsecondes. Cliquez ici pour en savoir plus sur le verrouillage lecteurs-rédacteurs.
Dans MongoDB, vous pouvez exécuter autant de requêtes simultanées que vous le souhaitez :tant que les données pertinentes sont en RAM, elles seront toutes satisfaites sans conflits de verrouillage.
Mises à jour des documents atomiques
Rappelons que dans MongoDB le niveau de transaction est un seul document. Toutes les mises à jour d'un seul document sont atomiques. MongoDB y parvient en maintenant le verrou d'écriture aussi longtemps qu'il le faut pour mettre à jour un seul document dans la RAM. S'il y a une opération lente (en particulier, si un document ou une entrée d'index doit être paginé à partir du disque), alors cette opération rendra le verrou d'écriture. Lorsque l'opération produit le verrou, l'opération suivante en file d'attente peut se poursuivre.
Cela signifie que les écritures sur tous les documents d'une même base de données sont sérialisées. Cela peut être un problème si vous avez une conception de schéma médiocre et que vos écritures prennent beaucoup de temps, mais dans un schéma correctement conçu, le verrouillage n'est pas un problème.
Écrivain gourmand
Quelques mots de plus sur l'avidité des écrivains :
Un seul graveur peut tenir le loquet à la fois; plusieurs lecteurs peuvent tenir le loquet à la fois. Dans une implémentation naïve, les écrivains pourraient mourir de faim indéfiniment s'il n'y avait qu'un seul lecteur en fonctionnement. Pour éviter cela, dans l'implémentation de MongoDB, une fois qu'un seul thread fait une demande d'écriture pour un verrou particulier
- Tous les lecteurs suivants nécessitant ce loquet seront bloqués
- Ce rédacteur attendra que tous les lecteurs actuels aient terminé
- L'écrivain acquerra le verrou d'écriture, fera son travail, puis relâchera le verrou d'écriture
- Tous les lecteurs en file d'attente vont maintenant continuer
Le comportement réel est complexe, car ce comportement gourmand en écriture interagit avec le rendement d'une manière qui peut ne pas être évidente. N'oubliez pas qu'à partir de la version 2.2, il existe une version séparée loquet pour chaque base de données, donc les écritures dans n'importe quelle collection de la base de données 'A' acquerront un loquet distinct que les écritures 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 détenus 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 effectue une série d'écritures, le verrou sera maintenu par base de données uniquement le temps nécessaire pour que cette écriture se termine
- Les connexions multiples entrant dans l'exécution d'écritures (mise à jour/insertion/suppression) seront toutes entrelacées
Bien que cela semble être un gros problème de performances, en 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 SSD, avant que le pourcentage de verrouillage sur une base de données ne dépasse 50 %.
Le cluster MongoDB de la plus grande capacité que je connaisse effectue actuellement 2 millions d'écritures par seconde.