Con il motore di archiviazione MMAPv1, gli aggiornamenti sul posto vengono spesso evidenziati come una strategia di ottimizzazione perché gli indici di un documento puntano direttamente alle posizioni dei file e si spostano. Lo spostamento di un documento in una nuova posizione di archiviazione (in particolare se sono presenti molte voci di indice da aggiornare) comporta un sovraccarico per MMAPv1 rispetto a un aggiornamento sul posto che deve solo aggiornare i campi modificati. Vedi:Caratteristiche di archiviazione dei record in MMAPv1.
WiredTiger non supporta gli aggiornamenti sul posto perché internamente utilizza MVCC (Multiversion Concurrency Control), che è comunemente usato dai sistemi di gestione dei database. Questo è un miglioramento tecnico significativo rispetto alla visualizzazione semplicistica in MMAP e consente di creare funzionalità più avanzate come livelli di isolamento e transazioni. Gli indici di WiredTiger hanno un livello di indirizzamento (riferito a un RecordID interno invece della posizione e dell'offset del file), quindi gli spostamenti dei documenti a livello di archiviazione non sono un punto dolente significativo.
Tuttavia, questo articolo dice anche che "Anche se [WiredTiger] non consente aggiornamenti sul posto, potrebbe comunque funzionare meglio di MMAP per molti carichi di lavoro".
Significa che sebbene MMAPv1 possa avere un percorso più efficiente per gli aggiornamenti sul posto, WiredTiger ha altri vantaggi come la compressione e un migliore controllo della concorrenza. Potresti forse costruire un carico di lavoro costituito solo da aggiornamenti sul posto di alcuni documenti che potrebbero funzionare meglio in MMAPv1, ma i carichi di lavoro effettivi sono in genere più vari. L'unico modo per confermare l'impatto di un determinato carico di lavoro sarebbe testare in un ambiente rappresentativo.
Tuttavia, la scelta generale di MMAPv1 vs WiredTiger è discutibile se si desidera pianificare per il futuro:WiredTiger è stato il motore di archiviazione predefinito da MongoDB 3.2 e alcune funzionalità del prodotto più recenti non sono supportate da MMAPv1. Ad esempio, MMAPv1 non supporta Majority Read Concern, il che a sua volta significa che non può essere utilizzato per Replica Set Config Servers (richiesto per lo sharding in MongoDB 3.4+) o Change Streams (MongoDB 3.6+). MMAPv1 sarà deprecato nella prossima versione principale di MongoDB (4.0) ed è attualmente programmato per essere rimosso in MongoDB 4.2.
Quali sono le esatte implicazioni di cui devo essere a conoscenza quando utilizzo WiredTiger? Ad esempio, senza aggiornamenti sul posto le dimensioni del database aumenteranno rapidamente?
I risultati dello storage dipendono da diversi fattori, tra cui la progettazione dello schema, il carico di lavoro, la configurazione e la versione del server MongoDB. MMAPv1 e WiredTiger utilizzano diverse strategie di allocazione dei record, ma entrambi cercheranno di utilizzare lo spazio preallocato contrassegnato come libero/riutilizzabile. In generale WiredTiger è più efficiente con l'uso dello spazio di archiviazione e ha anche il vantaggio della compressione per dati e indici. MMAPv1 alloca spazio di archiviazione aggiuntivo per cercare di ottimizzare gli aggiornamenti sul posto ed evitare gli spostamenti dei documenti, sebbene tu possa scegliere una strategia "senza riempimento" per le raccolte in cui il carico di lavoro non modifica le dimensioni del documento nel tempo.
Sono stati effettuati investimenti significativi nel miglioramento e nell'ottimizzazione di WiredTiger per diversi carichi di lavoro da quando è stato introdotto per la prima volta in MongoDB 3.0, quindi incoraggerei vivamente i test con le ultime serie di versioni di produzione per ottenere il miglior risultato. Se hai una domanda specifica sulla progettazione dello schema e sulla crescita dello spazio di archiviazione, suggerirei di pubblicare i dettagli su DBA StackExchange per la discussione.
Ho anche appreso che WiredTiger in MongoDB 3.6 ha aggiunto la capacità di memorizzare i delta anziché riscrivere l'intero documento (https://jira.mongodb.org/browse/DOCS-11416). Cosa significa esattamente?
Questo è un dettaglio di implementazione che migliora le strutture dati interne di WiredTiger per alcuni casi d'uso. In particolare, WiredTiger in MongoDB 3.6+ può essere più efficiente nel lavorare con piccole modifiche a documenti di grandi dimensioni (rispetto alle versioni precedenti). La cache di WiredTiger deve essere in grado di restituire più versioni di documenti purché vengano utilizzate da sessioni interne aperte (MVCC, come accennato in precedenza), quindi per documenti di grandi dimensioni con piccoli aggiornamenti potrebbe essere più efficiente archiviare un elenco di delta. Tuttavia, se si accumulano troppi delta (o i delta stanno modificando la maggior parte dei campi di un documento), questo approccio potrebbe essere meno efficace rispetto al mantenimento di più copie dell'intero documento.
Quando i dati vengono salvati su disco tramite un checkpoint, è comunque necessario scrivere una versione completa del documento. Se vuoi saperne di più su alcuni interni, c'è una serie di video MongoDB Path To Transactions che segue lo sviluppo di funzionalità per supportare le transazioni multi-documento in MongoDB 4.0.
Inoltre quello che non capisco è che al giorno d'oggi la maggior parte (se non tutti) i dischi rigidi hanno una dimensione del settore di 4096 byte, quindi non puoi scrivere sul disco rigido solo 4 byte (ad esempio) ma invece devi scrivere il blocco completo di 4096 byte (quindi leggilo prima, aggiorna i 4 byte e poi scrivilo). Poiché la maggior parte dei documenti è spesso <4096 byte, ciò significa che è comunque necessario riscrivere l'intero documento (anche con MMAP). Cosa mi sono perso?
Senza entrare troppo nei dettagli di implementazione e cercare di spiegare tutte le parti mobili coinvolte, considerare come i diversi approcci si applicano ai carichi di lavoro in cui vengono aggiornati molti documenti (piuttosto che a livello di singolo documento) nonché l'impatto sull'utilizzo della memoria (prima i documenti vengono scritti su disco). A seconda di fattori come la dimensione e la compressione del documento, un singolo blocco di I/O può rappresentare qualsiasi punto da una frazione di un documento (dimensione massima 16 MB) a più documenti.
In MongoDB il flusso generale è che i documenti vengono aggiornati in una vista in memoria (ad esempio, la cache di WiredTiger) con le modifiche persistenti sul disco in un formato journal di sola aggiunta veloce prima di essere periodicamente scaricati nei file di dati. Se il sistema operativo deve solo scrivere blocchi di dati che sono cambiati, toccare un numero inferiore di blocchi di dati richiede meno I/O complessivi.