MongoDB arbiters können Schreibvorgänge blockieren und die Dauerhaftigkeit schwächen
MongoDB arbiters können einem replica set dabei helfen, einen primary zu wählen, sie können jedoch keine Daten speichern, replizieren oder bestätigen. Laut Percona zeigen Supportfälle des Unternehmens, dass dieser Unterschied dazu führen kann, dass ein scheinbar intaktes Produktivsystem Schreibvorgänge drosselt, Timeouts verursacht oder bestätigte records durch rollback zurücksetzt.
Ein replica set ist eine Gruppe von MongoDB-Servern, die Kopien derselben Daten vorhalten. MongoDB führte den arbiter in seinen frühen Versionen im Jahr 2010 ein, damit Betreiber eine ungerade Anzahl von Stimmen einrichten konnten, ohne für einen weiteren datenhaltenden Server bezahlen zu müssen. Während einer election, dem Prozess zur Auswahl des Mitglieds, das primary wird, gibt der arbiter eine Stimme ab. Er wendet den oplog, MongoDBs geordnetes Protokoll der Datenbankänderungen, nicht an und hat die Dauerhaftigkeit der Daten nie verbessert.
Diese Einschränkung gewann während der MongoDB-3.x- und -4.x-Ära an Bedeutung. WiredTiger wurde zur standardmäßigen Storage Engine, während das replica-set-Protokoll auf pv1 umgestellt wurde. MongoDB machte außerdem readConcern und writeConcern, Einstellungen zur Steuerung, wie zuverlässig Lese- und Schreibvorgänge bestätigt werden müssen, zu zentralen Elementen der Dauerhaftigkeit. Change Streams, Transaktionen über mehrere Dokumente, flow control und clusterweite Standardwerte für read concern und write concern beruhen jeweils auf Formen einer majority-Vereinbarung. Ein arbiter zählt für eine election majority, jedoch nicht für die datenhaltende majority, die zum Bestätigen von Schreibvorgängen oder zum Fortschreiben des majority commit point erforderlich ist, also der neuesten Änderung, deren dauerhafte Replikation von genügend replicas bestätigt wurde.
Ein Supportfall von Percona betraf einen sharded cluster, der Daten auf mehrere replica sets verteilt. Er verfügte über drei shards und ein config-server replica set. Jeder shard hatte drei datenhaltende Mitglieder in einem Rechenzentrum, drei in einem zweiten und einen arbiter an einem dritten Standort. Dadurch ergaben sich sieben stimmberechtigte Mitglieder pro shard, von denen sechs Daten enthielten. Die config servers verwendeten dagegen sechs datenhaltende Mitglieder, jeweils zwei an jedem der drei Standorte und keinen arbiter.
Nach dem Ausfall eines Rechenzentrums wurden die elections abgeschlossen, und jeder shard wählte einen neuen primary. Der Schreibdurchsatz sank anschließend auf jedem shard von ungefähr 3.000 bis 4.000 Operationen pro Sekunde auf etwa 50 bis 75. Anwendungen stellten die Verbindung über mongos, den Query Router von MongoDB, her und verwendeten `{ w: 2, j: true }`. Dies erforderte die Bestätigung von zwei Mitgliedern einschließlich dauerhafter Speicherung im Journal. Auf jedem shard blieben drei datenhaltende Mitglieder und der arbiter erreichbar.
Das Problem lag nicht am von der Anwendung gewählten write concern, sondern an einer internen Operation. Einige Aufgaben eines sharded cluster, darunter Aktualisierungen des Collection Routing, führen lokal einen no-op aus – eine Operation, die keine Benutzerdaten verändert – und verwenden dabei majority write concern. Bei sieben stimmberechtigten Mitgliedern und einem arbiter betrug `writeMajorityCount` vier. Der arbiter konnte abstimmen, aber diesen Schreibvorgang nicht bestätigen. Daher konnten die drei verbliebenen datenhaltenden Mitglieder die Anforderung nicht erfüllen. Der majority commit point bewegte sich nicht mehr weiter, und die Routing-Aktualisierungen warteten auf einen fest codierten Timeout von ungefähr 60 Sekunden. Bei den config servers trat derselbe Fehler nicht auf, weil vier ihrer sechs datenhaltenden Mitglieder verfügbar blieben und damit ihre majority erreicht wurde.
Ein zweiter Fall zeigte, warum ein arbiter flow control, den Mechanismus von MongoDB zum Verlangsamen des primary, wenn replicas zu weit zurückfallen, nicht entlasten kann. Das replica set bestand aus vier datenhaltenden Mitgliedern, die gleichmäßig auf zwei Rechenzentren verteilt waren, sowie einem arbiter an einem dritten Standort. Zwei secondaries an einem Standort wiesen während einer hohen Schreiblast, die einen großen oplog auf dem primary erzeugte, einen replication lag von bis zu ungefähr 1.000 Sekunden auf. Der primary und sein lokaler secondary blieben auf dem aktuellen Stand, doch zum Fortschreiben des majority commit point waren drei der vier datenhaltenden Mitglieder erforderlich. Da nur zwei aufgeholt hatten, drosselte flow control die Schreibvorgänge des primary, obwohl der arbiter weiterhin verfügbar war.
Das schwerwiegendste Beispiel verwendete eine Primary-Secondary-Arbiter-Topologie, die üblicherweise als PSA abgekürzt wird. Der primary N1 hatte die election priority 2, und die Anwendung verwendete `w: 1`. Das bedeutete, dass ein Schreibvorgang bestätigt werden konnte, nachdem er nur ein Mitglied erreicht hatte. Als N1 abstürzte, wurde der secondary N2 zum primary und nahm ungefähr eine Stunde lang Schreibvorgänge an, die bestätigt wurden. Danach kehrte N1 zurück, doch bevor er aufgeholt hatte, fiel N2 aus. N1 und der arbiter bildeten eine voting majority, sodass N1 primary werden konnte, obwohl ihm die Änderungen dieser Stunde fehlten.
Als N2 dem System wieder beitrat, enthielt sein oplog hinter dem letzten mit N1 gemeinsam vorhandenen Stand einen neueren, aber widersprüchlichen Verlauf. MongoDB setzte diese Änderungen durch rollback zurück, damit die Daten mit dem gewählten primary übereinstimmten. Die Dokumente konnten nur deshalb wiederhergestellt werden, weil MongoDB sie als BSON-Dateien, seinem binären Dokumentformat, im rollback-Verzeichnis unter `dbPath`, dem Speicherort der Datenbank, aufbewahrt hatte. Sie waren nie an einen anderen Ort repliziert worden. Ein drittes datenhaltendes Mitglied, das auf dem aktuellen Stand geblieben wäre, hätte stattdessen einen neueren Stand als N1 haben und als primary infrage kommen können. Allerdings hätten auch dann abschließende Schreibvorgänge, die dieses Mitglied noch nicht erreicht hatten, durch rollback zurückgesetzt werden können.
Die dokumentierten Bereitstellungsempfehlungen von MongoDB spiegeln diese Risiken wider. Für Systeme mit drei Mitgliedern wird Primary-Secondary-Secondary beziehungsweise PSS empfohlen. PSA wird als kostengünstigere Ausweichlösung mit schwächerer Redundanz und Fehlertoleranz dargestellt, da nur zwei vollständige Datenkopien vorhanden sind. Ein arbiter sollte nicht denselben Host wie ein primary oder secondary verwenden, weil der Ausfall eines Hosts dann sowohl Daten als auch eine Stimme entfernen würde. Mehrere arbiters beeinträchtigen außerdem zuverlässige majority writes. Seit MongoDB 5.3 ist die Unterstützung mehrerer arbiters in einem replica set standardmäßig deaktiviert, weil ein System andernfalls Schreibvorgänge annehmen könnte, ohne über genügend secondaries für deren Replikation zu verfügen.
Arbiters schränken außerdem Transaktionen ein. Ein shard key kann nicht über eine Transaktion geändert werden, wenn das replica set einen arbiter enthält. Da arbiters die für Transaktionen über mehrere shards erforderlichen Datenoperationen nicht ausführen können, verursacht eine solche Transaktion einen Fehler und wird abgebrochen, wenn eine Operation Daten aus einem shard mit einem arbiter liest oder darauf schreibt. MongoDB Atlas unterstützt arbiters in keiner Tarifstufe.
Die praktische Schlussfolgerung lautet, die Verfügbarkeit von Stimmen und die Dauerhaftigkeit der Daten getrennt zu bewerten. Eine Statusanzeige kann eine erfolgreiche election melden, während die Datenbank majority commits nicht fortschreiben, mit der Replikation nicht Schritt halten oder bestätigte Schreibvorgänge nicht bewahren kann. Teams sollten replication lag, Schreiblatenz und die Bewegung des commit point überwachen, vollständige Standortausfälle testen und write concerns wählen, die der Bedeutung der Daten entsprechen. Organisationen, die entscheiden, wo sie diese Systeme betreiben möchten, erhalten bei AEU Data europäische Cloud- und Dateninfrastruktur. Ein solides Design des replica set bleibt jedoch eine betriebliche Verantwortung.
Das Ersetzen eines arbiter durch ein datenhaltendes Mitglied erfordert mehr Kapazität, fügt jedoch eine weitere Kopie hinzu, die Schreibvorgänge bestätigen und bewahren kann. Die Fälle von Percona zeigen, dass das günstigere stimmberechtigte Mitglied höhere Betriebskosten verursachen kann, wenn Schreibvorgänge blockieren, Transaktionen fehlschlagen oder records nur in rollback-Dateien erhalten bleiben.