MongoDB-låsning er anderledes
Låsning i MongoDB fungerer ikke som at låse i en RDBMS, så lidt forklaring er på sin plads. I tidligere versioner af MongoDB var der en enkelt global læser/skriverlås. Fra og med MongoDB 2.2 er der en læser/skriverlås til hver database.
Læser-skriver-låsen
Låsen er flerlæser, enkeltforfatter og er forfattergrådig. Det betyder, at:
- Der kan være et ubegrænset antal samtidige læsere i en database
- Der kan kun være én forfatter ad gangen på en samling i en database (mere om dette om lidt)
- Forfattere blokerer læsere
- Med "skribent-greedy" mener jeg, at når en skriveanmodning kommer ind, er alle læsere blokeret, indtil skrivningen er færdig (mere om dette senere)
Bemærk, at jeg kalder dette en "lås" i stedet for en "lås". Dette skyldes, at det er let, og i et korrekt designet skema holdes skrivelåsen i størrelsesordenen et dusin mikrosekunder. Se her for mere om læser-skriver-låsning.
I MongoDB kan du køre så mange samtidige forespørgsler, som du vil:så længe de relevante data er i RAM, vil de alle blive tilfredsstillet uden låsekonflikter.
Atomic Document Updates
Husk på, at i MongoDB er transaktionsniveauet et enkelt dokument. Alle opdateringer til et enkelt dokument er Atomic. MongoDB opnår dette ved kun at holde skrivelåsen så længe, som det tager at opdatere et enkelt dokument i RAM. Hvis der er en langsomt kørende operation (især hvis et dokument eller en indekspost skal indlæses fra disken), så vil den operation give skrivelåsen. Når operationen giver låsen, kan den næste handling i kø fortsætte.
Dette betyder, at skrivningerne til alle dokumenter i en enkelt database bliver serialiseret. Dette kan være et problem, hvis du har et dårligt skemadesign, og dine skrivninger tager lang tid, men i et korrekt designet skema er låsning ikke et problem.
Grådrig forfatter
Et par ord mere om at være forfattergrådig:
Kun én forfatter kan holde låsen ad gangen; flere læsere kan holde låsen ad gangen. I en naiv implementering kunne forfattere sulte i det uendelige, hvis der var en enkelt læser i drift. For at undgå dette, i MongoDB-implementeringen, når en enkelt tråd laver en skriveanmodning om en bestemt lås
- Alle efterfølgende læsere, der har brug for den lås, vil blokere
- Denne forfatter vil vente, indtil alle nuværende læsere er færdige
- Forfatteren anskaffer skrivelåsen, udfører sit arbejde og frigiver derefter skrivelåsen
- Alle læsere i kø fortsætter nu
Den faktiske adfærd er kompleks, da denne forfattergrådige adfærd interagerer med eftergivelse på måder, der kan være ikke-indlysende. Husk, at der starter med version 2.2, er en separat latch for hver database, så skrivning til enhver samling i databasen 'A' vil få en separat latch end skrivning til enhver samling i databasen 'B'.
Konkrete spørgsmål
Angående de specifikke spørgsmål:
- Låse (faktisk låse) holdes af MongoDB-kernen, så længe det tager at opdatere et enkelt dokument
- Hvis du har flere forbindelser, der kommer ind til MongoDB, og hver enkelt af dem udfører en række skrivninger, vil låsen kun blive holdt på en per-database-basis, så længe det tager for den skrivning at fuldføre li>
- Flere forbindelser, der kommer til at skrive (opdater/indsæt/slet), bliver alle sammenflettet
Selvom dette lyder som om det ville være en stor ydeevne bekymring, bremser det i praksis ikke tingene. Med et korrekt designet skema og en typisk arbejdsbyrde vil MongoDB mætte diskens I/O-kapacitet -- selv for en SSD -- før låseprocenten på en database går over 50 %.
Den højeste kapacitet MongoDB-klynge, som jeg er bekendt med, udfører i øjeblikket 2 millioner skrivninger i sekundet.