Bei der MMAPv1-Speicher-Engine werden In-Place-Updates häufig als Optimierungsstrategie hervorgehoben, da Indizes für ein Dokument direkt auf Dateispeicherorte und -offsets verweisen. Das Verschieben eines Dokuments an einen neuen Speicherort (insbesondere wenn viele Indexeinträge zu aktualisieren sind) verursacht für MMAPv1 mehr Overhead als eine direkte Aktualisierung, bei der nur die geänderten Felder aktualisiert werden müssen. Siehe:Aufzeichnungsspeichermerkmale in MMAPv1.
WiredTiger unterstützt keine In-Place-Updates, da es intern MVCC (Multiversion Concurrency Control) verwendet, das häufig von Datenbankverwaltungssystemen verwendet wird. Dies ist eine erhebliche technische Verbesserung gegenüber der vereinfachten Ansicht in MMAP und ermöglicht die Erstellung erweiterter Funktionen wie Isolationsstufen und Transaktionen. Die Indizes von WiredTiger verfügen über eine Indirektionsebene (die auf eine interne Datensatz-ID anstelle des Dateispeicherorts und -versatzes verweist), sodass Dokumentverschiebungen auf Speicherebene kein wesentlicher Schmerzpunkt sind.
In diesem Artikel heißt es jedoch auch:„Obwohl [WiredTiger] keine In-Place-Updates zulässt, könnte es für viele Workloads dennoch eine bessere Leistung als MMAP erbringen.“
Das bedeutet, dass MMAPv1 zwar einen effizienteren Weg für In-Place-Updates bietet, WiredTiger jedoch andere Vorteile wie Komprimierung und verbesserte Parallelitätssteuerung bietet. Sie könnten vielleicht eine Workload erstellen, die nur aus direkten Aktualisierungen einiger weniger Dokumente besteht, die in MMAPv1 möglicherweise eine bessere Leistung erbringen, aber die tatsächlichen Workloads sind in der Regel vielfältiger. Die einzige Möglichkeit, die Auswirkungen für eine bestimmte Arbeitslast zu bestätigen, besteht darin, sie in einer repräsentativen Umgebung zu testen.
Die generelle Wahl zwischen MMAPv1 und WiredTiger ist jedoch umstritten, wenn Sie für die Zukunft planen möchten:WiredTiger ist seit MongoDB 3.2 die Standardspeicher-Engine, und einige neuere Produktfunktionen werden von MMAPv1 nicht unterstützt. Beispielsweise unterstützt MMAPv1 Majority Read Concern nicht, was wiederum bedeutet, dass es nicht für Replica Set Config Server (erforderlich für Sharding in MongoDB 3.4+) oder Change Streams (MongoDB 3.6+) verwendet werden kann. MMAPv1 wird in der nächsten Hauptversion von MongoDB (4.0) veraltet sein und soll derzeit in MongoDB 4.2 entfernt werden.
Was sind die genauen Auswirkungen, die ich beachten muss, wenn ich WiredTiger verwende? Wird beispielsweise die Datenbankgröße ohne In-Place-Updates schnell wachsen?
Die Speicherergebnisse hängen von mehreren Faktoren ab, darunter Schemadesign, Workload, Konfiguration und Version des MongoDB-Servers. MMAPv1 und WiredTiger verwenden unterschiedliche Datensatzzuweisungsstrategien, aber beide versuchen, vorab zugewiesenen Speicherplatz zu verwenden, der als frei/wiederverwendbar markiert ist. Im Allgemeinen ist WiredTiger effizienter bei der Nutzung des Speicherplatzes und hat auch den Vorteil der Komprimierung für Daten und Indizes. MMAPv1 weist zusätzlichen Speicherplatz zu, um zu versuchen, direkte Aktualisierungen zu optimieren und Dokumentverschiebungen zu vermeiden, obwohl Sie für Sammlungen, bei denen die Arbeitslast die Dokumentgröße im Laufe der Zeit nicht ändert, eine Strategie ohne Auffüllung wählen können.
Seit seiner ersten Einführung in MongoDB 3.0 wurde erheblich in die Verbesserung und Abstimmung von WiredTiger für verschiedene Workloads investiert, daher würde ich dringend dazu ermutigen, Tests mit der neuesten Produktionsversionsreihe durchzuführen, um das beste Ergebnis zu erzielen. Wenn Sie eine spezifische Frage zum Schemadesign und Speicherwachstum haben, würde ich vorschlagen, Details zur Diskussion auf DBA StackExchange zu posten.
Ich habe auch erfahren, dass WiredTiger in MongoDB 3.6 die Möglichkeit hinzugefügt hat, Deltas zu speichern, anstatt das gesamte Dokument neu zu schreiben (https://jira.mongodb.org/browse/DOCS-11416). Was bedeutet das genau?
Dies ist ein Implementierungsdetail, das die internen Datenstrukturen von WiredTiger für einige Anwendungsfälle verbessert. Insbesondere kann WiredTiger in MongoDB 3.6+ beim Arbeiten mit kleinen Änderungen an großen Dokumenten effizienter sein (im Vergleich zu früheren Versionen). Der WiredTiger-Cache muss in der Lage sein, mehrere Versionen von Dokumenten zurückzugeben, solange sie von offenen internen Sitzungen (MVCC, wie zuvor erwähnt) verwendet werden. Daher könnte es für große Dokumente mit kleinen Aktualisierungen effizienter sein, eine Liste von Deltas zu speichern. Wenn sich jedoch zu viele Deltas ansammeln (oder die Deltas die meisten Felder in einem Dokument ändern), könnte dieser Ansatz weniger leistungsfähig sein als die Verwaltung mehrerer Kopien des vollständigen Dokuments.
Wenn Daten über einen Prüfpunkt auf die Festplatte übertragen werden, muss noch eine vollständige Version des Dokuments geschrieben werden. Wenn Sie mehr über einige der Interna erfahren möchten, gibt es eine MongoDB Path To Transactions-Videoreihe, die die Entwicklung von Funktionen zur Unterstützung von Transaktionen mit mehreren Dokumenten in MongoDB 4.0 verfolgt.
Was ich auch nicht verstehe, ist, dass heutzutage die meisten (wenn nicht alle) Festplatten eine Sektorgröße von 4096 Bytes haben, sodass Sie nicht nur 4 Bytes (zum Beispiel) auf die Festplatte schreiben können, sondern stattdessen den vollen Block von 4096 schreiben müssen Bytes (also zuerst lesen, die 4 Bytes darin aktualisieren und dann schreiben). Da die meisten Dokumente oft <4096 Bytes groß sind, bedeutet dies, dass in jedem Fall das gesamte Dokument neu geschrieben werden muss (auch bei MMAP). Was habe ich verpasst?
Ohne zu weit in die Implementierungsdetails einzusteigen und zu versuchen, alle beteiligten beweglichen Teile zu erklären, überlegen Sie, wie sich die verschiedenen Ansätze auf Workloads beziehen, bei denen viele Dokumente aktualisiert werden (und nicht auf der Ebene einzelner Dokumente), sowie die Auswirkungen auf die Speichernutzung (vorher Dokumente werden auf die Festplatte geschrieben). Abhängig von Faktoren wie Dokumentgröße und Komprimierung kann ein einzelner E/A-Block einen Bruchteil eines Dokuments (maximale Größe 16 MB) bis hin zu mehreren Dokumenten darstellen.
In MongoDB besteht der allgemeine Ablauf darin, dass Dokumente in einer In-Memory-Ansicht (z. B. dem WiredTiger-Cache) aktualisiert werden, wobei Änderungen in einem schnellen Nur-Anhänge-Journalformat auf der Festplatte gespeichert werden, bevor sie regelmäßig in die Datendateien geleert werden. Wenn das Betriebssystem nur geänderte Datenblöcke schreiben muss, erfordert das Berühren von weniger Datenblöcken insgesamt weniger I/O.