Il blocco di MongoDB è diverso
Il blocco in MongoDB non funziona come il blocco in un RDBMS, quindi è necessario un po' di spiegazione. Nelle versioni precedenti di MongoDB, c'era un unico blocco di lettura/scrittura globale. A partire da MongoDB 2.2, c'è un latch di lettura/scrittura per ogni database.
L'aggancio lettori-scrittori
Il fermo è a lettore multiplo, a scrittore singolo ed è avido di scrittore. Ciò significa che:
- Ci può essere un numero illimitato di lettori simultanei su un database
- Può esserci solo uno scrittore alla volta su qualsiasi raccolta in qualsiasi database (ne parleremo tra poco)
- Gli autori bloccano i lettori
- Con "writer-greedy", intendo che una volta ricevuta una richiesta di scrittura, tutti i lettori vengono bloccati fino al completamento della scrittura (ne parleremo più avanti)
Nota che lo chiamo un "fermo" piuttosto che un "blocco". Questo perché è leggero e in uno schema correttamente progettato il blocco di scrittura viene mantenuto nell'ordine di una dozzina di microsecondi. Vedi qui per ulteriori informazioni sul blocco lettori-scrittori.
In MongoDB puoi eseguire tutte le query simultanee che desideri:finché i dati rilevanti sono nella RAM saranno tutti soddisfatti senza conflitti di blocco.
Aggiornamenti del documento atomico
Ricordiamo che in MongoDB il livello di transazione è un unico documento. Tutti gli aggiornamenti a un singolo documento sono atomici. MongoDB ottiene ciò mantenendo il fermo di scrittura solo per il tempo necessario per aggiornare un singolo documento nella RAM. Se è presente un'operazione a esecuzione lenta (in particolare, se è necessario eseguire il paging di un documento o di una voce di indice dal disco), l'operazione rende il fermo di scrittura. Quando l'operazione restituisce il latch, l'operazione successiva in coda può procedere.
Ciò significa che le scritture su tutti i documenti all'interno di un singolo database vengono serializzate. Questo può essere un problema se hai una progettazione dello schema scadente e le tue scritture richiedono molto tempo, ma in uno schema progettato correttamente, il blocco non è un problema.
Scrittore-Avido
Qualche parola in più sull'essere avidi di scrittori:
Solo uno scrittore alla volta può tenere il fermo; più lettori possono tenere il fermo alla volta. In un'implementazione ingenua, gli scrittori potrebbero morire di fame indefinitamente se ci fosse un solo lettore in funzione. Per evitare ciò, nell'implementazione di MongoDB, una volta che un singolo thread effettua una richiesta di scrittura per un particolare latch
- Tutti i lettori successivi che necessitano di quel latch verranno bloccati
- Quello scrittore aspetterà finché tutti i lettori attuali non saranno terminati
- Lo scrittore acquisirà il latch di scrittura, farà il suo lavoro e quindi rilascerà il latch di scrittura
- Ora procederanno tutti i lettori in coda
Il comportamento reale è complesso, dal momento che questo comportamento avido di scrittore interagisce con la resa in modi che possono essere non ovvi. Ricordiamo che, a partire dalla release 2.2, esiste un separato latch per ogni database, quindi le scritture in qualsiasi raccolta nel database "A" acquisiranno un latch separato rispetto alle scritture in qualsiasi raccolta nel database "B".
Domande specifiche
Per quanto riguarda le domande specifiche:
- I blocchi (in realtà i latch) sono mantenuti dal kernel MongoDB solo per il tempo necessario per aggiornare un singolo documento
- Se hai più connessioni in entrata a MongoDB e ognuna di esse sta eseguendo una serie di scritture, il latch verrà mantenuto in base al database solo per il tempo necessario al completamento della scrittura li>
- Più connessioni in entrata in fase di scrittura (aggiornamento/inserimento/eliminazione) verranno tutte intercalate
Anche se questo suona come un grosso problema di prestazioni, in pratica non rallenta le cose. Con uno schema adeguatamente progettato e un carico di lavoro tipico, MongoDB saturerà la capacità di I/O del disco, anche per un SSD, prima che la percentuale di blocco su qualsiasi database superi il 50%.
Il cluster MongoDB con la capacità più alta di cui sono a conoscenza sta attualmente eseguendo 2 milioni di scritture al secondo.