MongoDB-vergrendeling is anders
Vergrendelen in MongoDB werkt niet zoals vergrendelen in een RDBMS, dus een beetje uitleg is op zijn plaats. In eerdere versies van MongoDB was er één globale lezer/schrijver-vergrendeling. Vanaf MongoDB 2.2 is er een reader/writer-latch voor elke database.
De reader-writer-vergrendeling
De vergrendeling is voor meerdere lezers, één schrijver en is hebzuchtig voor schrijvers. Dit betekent dat:
- Er kan een onbeperkt aantal gelijktijdige lezers in een database zijn
- Er kan maar één schrijver tegelijk zijn voor een verzameling in een database (hierover later meer)
- Schrijvers blokkeren lezers
- Met "schrijver-hebzuchtig" bedoel ik dat zodra een schrijfverzoek binnenkomt, alle lezers worden geblokkeerd totdat het schrijven is voltooid (hierover later meer)
Merk op dat ik dit een "grendel" noem in plaats van een "slot". Dit komt omdat het licht van gewicht is, en in een goed ontworpen schema wordt de schrijfvergrendeling in de orde van grootte van een tiental microseconden vastgehouden. Zie hier voor meer informatie over het vergrendelen van lezers en schrijvers.
In MongoDB kunt u zoveel gelijktijdige zoekopdrachten uitvoeren als u wilt:zolang de relevante gegevens zich in het RAM bevinden, worden ze allemaal vervuld zonder vergrendelingsconflicten.
Atomic Document Updates
Bedenk dat in MongoDB het transactieniveau één enkel document is. Alle updates voor een enkel document zijn Atomic. MongoDB bereikt dit door de schrijfvergrendeling slechts zo lang vast te houden als nodig is om een enkel document in RAM bij te werken. Als er een langzaam lopende bewerking is (in het bijzonder als een document of een indexitem moet worden ingewisseld vanaf schijf), dan zal die bewerking opbrengen de schrijfvergrendeling. Wanneer de bewerking de vergrendeling oplevert, kan de volgende bewerking in de wachtrij doorgaan.
Dit betekent wel dat de schrijfbewerkingen naar alle documenten binnen een enkele database geserialiseerd worden. Dit kan een probleem zijn als je een slecht schema-ontwerp hebt en het schrijven lang duurt, maar in een goed ontworpen schema is vergrendeling geen probleem.
Schrijver-hebzuchtig
Nog een paar woorden over hebzuchtig schrijvers zijn:
Slechts één schrijver kan de grendel tegelijk vasthouden; meerdere lezers kunnen de vergrendeling tegelijk vasthouden. In een naïeve implementatie zouden schrijvers voor onbepaalde tijd kunnen verhongeren als er maar één lezer in gebruik was. Om dit te voorkomen, in de MongoDB-implementatie, zodra een enkele thread een schrijfverzoek doet voor een bepaalde vergrendeling
- Alle volgende lezers die die vergrendeling nodig hebben, worden geblokkeerd
- Die schrijver zal wachten tot alle huidige lezers klaar zijn
- De schrijver verwerft de schrijfgrendel, doet zijn werk en laat dan de schrijfgrendel los
- Alle lezers in de wachtrij gaan nu verder
Het feitelijke gedrag is complex, omdat dit hebzuchtige gedrag op schrijvers in wisselwerking staat met toegeven op manieren die niet voor de hand liggend kunnen zijn. Bedenk dat er vanaf release 2.2 een aparte . is vergrendeling voor elke database, dus schrijven naar een verzameling in database 'A' krijgt een aparte vergrendeling dan schrijven naar een verzameling in database 'B'.
Specifieke vragen
Wat betreft de specifieke vragen:
- Vergrendelingen (eigenlijk vergrendelingen) worden door de MongoDB-kernel slechts zo lang vastgehouden als nodig is om een enkel document bij te werken
- Als er meerdere verbindingen binnenkomen in MongoDB, en elk van hen voert een reeks schrijfbewerkingen uit, wordt de vergrendeling per database slechts zo lang vastgehouden als nodig is om die schrijfbewerking te voltooien li>
- Meerdere verbindingen die binnenkomen bij het uitvoeren van schrijfbewerkingen (update/insert/delete) worden allemaal tussengevoegd
Hoewel dit klinkt alsof het een groot prestatieprobleem zou zijn, vertraagt het in de praktijk de zaken niet. Met een goed ontworpen schema en een typische werklast, zal MongoDB de schijf-I/O-capaciteit verzadigen - zelfs voor een SSD - voordat het vergrendelingspercentage van een database boven de 50% komt.
Het MongoDB-cluster met de hoogste capaciteit dat ik ken, voert momenteel 2 miljoen schrijfbewerkingen per seconde uit.