
Fehlertoleranz und hohe Verfügbarkeit sind große Themen, daher werden wir RabbitMQ und Kafka separate Artikel widmen. In diesem Artikel geht es um RabbitMQ und im nächsten um Kafka im Vergleich zu RabbitMQ. Dies ist ein langer Artikel, also machen Sie es sich bequem.
Sehen wir uns Strategien für Fehlertoleranz, Konsistenz und hohe Verfügbarkeit (HA) sowie die mit jeder Strategie verbundenen Kompromisse an. RabbitMQ kann auf einem Cluster von Knoten ausgeführt werden – und wird dann als verteiltes System klassifiziert. Wenn wir über verteilte Systeme sprechen, sprechen wir oft über Konsistenz und Verfügbarkeit.
Diese Konzepte beschreiben, wie sich das System verhält, wenn ein Fehler auftritt. Netzwerkverbindungsfehler, Serverfehler, Festplattenfehler, Server aufgrund von Garbage Collection, Paketverlust oder langsamer Netzwerkverbindung vorübergehend nicht verfügbar. All dies kann zu Datenverlust oder Konflikten führen. Es stellt sich heraus, dass es praktisch unmöglich ist, ein System zu erstellen, das sowohl vollständig konsistent (kein Datenverlust, keine Datenabweichungen) als auch zugänglich (akzeptiert Lese- und Schreibvorgänge) für alle Fehlermodi ist.
Wir werden sehen, dass Konsistenz und Verfügbarkeit an unterschiedlichen Enden des Spektrums liegen und Sie entscheiden müssen, welches davon Sie optimieren möchten. Die gute Nachricht ist, dass diese Wahl mit RabbitMQ möglich ist. Sie haben diese kleinen, nerdigen Hebel, um das Gleichgewicht in Richtung mehr Kohärenz oder mehr Zugänglichkeit zu verschieben.
Dabei achten wir besonders darauf, welche Konfigurationen zu Datenverlusten durch festgeschriebene Datensätze führen. Es besteht eine Verantwortungskette zwischen Herausgebern, Maklern und Verbrauchern. Sobald eine Nachricht an den Broker weitergeleitet wurde, ist es seine Aufgabe, dafür zu sorgen, dass die Nachricht nicht verloren geht. Wenn ein Broker einem Herausgeber den Empfang einer Nachricht bestätigt, gehen wir nicht davon aus, dass diese verloren geht. Wir werden jedoch sehen, dass dies je nach Broker- und Publisher-Konfiguration tatsächlich passieren kann.
Einzelknoten-Stabilitätsprimitive
Permanente Warteschlangen/Routing
RabbitMQ hat zwei Warteschlangentypen: dauerhaft und nicht dauerhaft. Alle Warteschlangen werden in der Mnesia-Datenbank gespeichert. Dauerhafte Warteschlangen werden beim Start eines Knotens erneut angekündigt und überstehen daher einen Neustart, einen Systemabsturz oder einen Serverausfall (solange die Daten bestehen bleiben). Dies bedeutet, dass die Warteschlangen-/Routing-Infrastruktur wieder online geht, solange Sie den Austausch und die Warteschlange als ausfallsicher deklarieren.
Instabile Warteschlangen und Routing werden beim Neustart des Knotens entfernt.
Dauerhafte Nachrichten
Nur weil eine Warteschlange langlebig ist, bedeutet das nicht, dass alle darin enthaltenen Nachrichten einen Knotenneustart überstehen. Nur vom Herausgeber als nachhaltig (hartnäckig). Permanente Nachrichten verursachen zwar eine zusätzliche Belastung für den Broker, aber wenn ein Nachrichtenverlust nicht akzeptabel ist, gibt es keine andere Möglichkeit.

Reis. 1. Stabilitätsmatrix
Clustering mit Warteschlangenspiegelung
Um den Verlust eines Maklers zu überstehen, brauchen wir Redundanz. Wir können mehrere RabbitMQ-Knoten zu einem Cluster kombinieren und dann zusätzliche Redundanz hinzufügen, indem wir Warteschlangen über mehrere Knoten hinweg replizieren. Auf diese Weise gehen keine Daten verloren, wenn ein Knoten ausfällt, und wir bleiben verfügbar.
Warteschlangenspiegelung:
- eine Hauptwarteschlange (Master), die alle Schreib- und Lesebefehle empfängt
- ein oder mehrere Spiegel, die alle Nachrichten und Metadaten aus der Hauptwarteschlange empfangen. Diese Spiegel dienen nicht der Skalierung, sondern ausschließlich der Redundanz.

Reis. 2. Warteschlangenspiegelung
Die Spiegelung wird durch die entsprechende Richtlinie festgelegt. Darin können Sie den Replikationsfaktor und sogar die Knoten auswählen, auf denen die Warteschlange platziert werden soll. Beispiele:
ha-mode: allha-mode: exactly, ha-params: 2(ein Master und ein Spiegel)ha-mode: nodes, ha-params: rabbit@node1, rabbit@node2
Bestätigung an den Verlag
Um eine konsistente Aufzeichnung zu erreichen, sind Bestätigungen des Herausgebers erforderlich. Ohne sie besteht die Gefahr, dass Nachrichten verloren gehen. Nachdem die Nachricht auf die Festplatte geschrieben wurde, wird eine Bestätigung an den Herausgeber gesendet. RabbitMQ schreibt Nachrichten nicht sofort nach Erhalt auf die Festplatte, sondern in regelmäßigen Abständen im Abstand von einigen hundert Millisekunden. Wenn eine Warteschlange gespiegelt wird, wird eine Bestätigung erst gesendet, nachdem alle Spiegel ihre Kopie der Nachricht ebenfalls auf die Festplatte geschrieben haben. Dies bedeutet, dass die Verwendung von Bestätigungen zu einer zusätzlichen Latenz führt, diese jedoch erforderlich sind, wenn Datensicherheit wichtig ist.
Fehlertolerante Warteschlange
Wenn ein Broker beendet wird oder abstürzt, fallen auch alle Master auf diesem Knoten aus. Der Cluster wählt dann den ältesten Spiegel jedes Masters aus und ernennt ihn zum neuen Master.

Reis. 3. Mehrere gespiegelte Warteschlangen und ihre Richtlinien
Broker 3 ist ausgefallen. Bitte beachten Sie, dass der Queue C-Spiegel auf Broker 2 zum Master befördert wird. Beachten Sie auch, dass für Warteschlange C auf Broker 1 ein neuer Spiegel erstellt wurde. RabbitMQ versucht immer, den in Ihren Richtlinien angegebenen Replikationsfaktor beizubehalten.

Reis. 4. Broker 3 fällt aus, wodurch Warteschlange C ausfällt.
Der nächste Broker 1 fällt! Wir haben nur noch einen Makler übrig. Der Spiegel der Warteschlange B wird zum Master befördert.

Fig. 5
Wir haben Broker 1 zurückgebracht. Unabhängig davon, wie gut die Daten den Verlust und die Wiederherstellung des Brokers überstanden haben, werden alle gespiegelten Warteschlangennachrichten beim Neustart verworfen. Dies ist wichtig zu beachten, da dies Konsequenzen haben wird. Wir werden uns diese Auswirkungen in Kürze ansehen. Broker 1 ist jetzt also wieder Mitglied des Clusters und der Cluster versucht, die Richtlinien einzuhalten und erstellt daher Spiegel auf Broker 1.
In diesem Fall kam es zum Totalverlust von Broker 1 und den Daten, sodass die ungespiegelte Warteschlange B vollständig verloren ging.

Reis. 6. Broker 1 ist wieder im Einsatz
Broker 3 ist wieder online, sodass die Spiegelbilder der Warteschlangen A und B wieder darauf erstellt werden, um ihre HA-Richtlinien zu erfüllen. Aber jetzt befinden sich alle Hauptwarteschlangen auf einem Knoten! Dies ist nicht ideal, eine gleichmäßige Verteilung zwischen den Knoten ist besser. Spezielle Möglichkeiten zum Rebalancing von Mastern gibt es hier leider nicht. Wir werden später auf dieses Problem zurückkommen, da wir zuerst die Warteschlangensynchronisierung berücksichtigen müssen.

Reis. 7. Broker 3 nimmt den Dienst wieder auf. Alle Hauptwarteschlangen auf einem Knoten!
Sie sollten jetzt eine Vorstellung davon haben, wie Spiegel Redundanz und Fehlertoleranz bieten. Dies stellt die Verfügbarkeit beim Ausfall eines einzelnen Knotens sicher und schützt vor Datenverlust. Aber wir sind noch nicht fertig, denn in Wirklichkeit ist alles viel komplizierter.
Synchronisation
Wenn Sie einen neuen Spiegel erstellen, werden alle neuen Nachrichten immer auf diesen und alle anderen Spiegel repliziert. Was die vorhandenen Daten in der Master-Warteschlange betrifft, können wir sie auf einen neuen Spiegel replizieren, der zu einer vollständigen Kopie des Masters wird. Wir können uns auch dafür entscheiden, vorhandene Nachrichten nicht zu replizieren und die Hauptwarteschlange und den neuen Spiegel rechtzeitig zusammenlaufen zu lassen, wenn neue Nachrichten am Ende ankommen und vorhandene Nachrichten den Anfang der Hauptwarteschlange verlassen.
Diese Synchronisierung wird automatisch oder manuell durchgeführt und durch eine Warteschlangenrichtlinie gesteuert. Schauen wir uns ein Beispiel an.
Wir haben zwei gespiegelte Warteschlangen. Warteschlange A wird automatisch synchronisiert, während Warteschlange B manuell synchronisiert wird. In beiden Warteschlangen befinden sich zehn Nachrichten.

Reis. 8. Zwei Warteschlangen mit unterschiedlichen Synchronisationsmodi
Jetzt verlieren wir Broker 3.

Reis. 9. Broker 3 fiel
Broker 3 ist wieder im Einsatz. Der Cluster erstellt für jede Warteschlange auf dem neuen Knoten einen Spiegel und synchronisiert die neue Warteschlange A automatisch mit dem Master. Der Spiegel der neuen Warteschlange B bleibt jedoch leer. Somit verfügen wir über eine vollständige Redundanz der Warteschlange A und nur über einen Spiegel für vorhandene Nachrichten der Warteschlange B.

Reis. 10. Der neue Spiegel von Warteschlange A empfängt alle vorhandenen Nachrichten, der neue Spiegel von Warteschlange B jedoch nicht.
In beiden Warteschlangen treffen zehn weitere Nachrichten ein. Dann stürzt Broker 2 ab und Warteschlange A wird auf den ältesten Spiegel zurückgesetzt, der sich auf Broker 1 befindet. Beim Absturz kommt es zu keinem Datenverlust. Warteschlange B hat zwanzig Nachrichten auf dem Master und nur zehn auf dem Spiegel, weil diese Warteschlange die ursprünglichen zehn Nachrichten nie repliziert hat.

Reis. 11. Warteschlange A wird ohne Nachrichtenverlust zu Broker 1 zurückgesetzt
In beiden Warteschlangen treffen zehn weitere Nachrichten ein. Jetzt stürzt Broker 1 ab. Warteschlange A wechselt problemlos und ohne Nachrichtenverlust zum Spiegel. Allerdings treten bei Warteschlange B Probleme auf. In dieser Phase können wir entweder die Verfügbarkeit oder die Konsistenz optimieren.
Wenn wir die Zugänglichkeit optimieren wollen, dann muss die Politik ha-promote-on-failure sollte installiert werden in immer. Dies ist der Standardwert, Sie können die Richtlinie also einfach gar nicht angeben. In diesem Fall lassen wir im Wesentlichen Fehler in nicht synchronisierten Spiegeln zu. Dies führt dazu, dass Nachrichten verloren gehen, die Warteschlange jedoch weiterhin zum Lesen und Schreiben verfügbar bleibt.

Reis. 12. Warteschlange A wird ohne Nachrichtenverlust zu Broker 3 zurückgesetzt. Warteschlange B fällt mit dem Verlust von zehn Nachrichten auf Broker 3 zurück
Wir können auch installieren ha-promote-on-failure in die Bedeutung when-synced. In diesem Fall wird die Warteschlange nicht zurück zum Spiegel verschoben, sondern wartet, bis Broker 1 mit seinen Daten in den Betriebsmodus zurückkehrt. Nach seiner Rückkehr steht die Hauptwarteschlange wieder ohne Datenverlust auf Broker 1. Die Verfügbarkeit wird der Datensicherheit geopfert. Dies ist jedoch ein riskanter Modus, der sogar zu einem vollständigen Datenverlust führen kann, worauf wir gleich näher eingehen werden.

Reis. 13. Warteschlange B bleibt nach dem Verlust von Broker 1 nicht verfügbar
Sie fragen sich vielleicht: „Vielleicht ist es besser, die automatische Synchronisierung nie zu verwenden?“ Die Antwort ist, dass die Synchronisierung ein blockierender Vorgang ist. Während der Synchronisierung kann die Hauptwarteschlange keine Lese- oder Schreibvorgänge ausführen!
Schauen wir uns ein Beispiel an. Wir haben jetzt sehr lange Warteschlangen. Wie können sie eine solche Größe erreichen? Aus mehreren Gründen:
- Warteschlangen werden nicht aktiv genutzt
- Dabei handelt es sich um Hochgeschwindigkeitswarteschlangen, und derzeit arbeiten die Verbraucher langsam.
- Dies sind Hochgeschwindigkeitswarteschlangen, es gab eine Störung, und die Verbraucher holen auf

Reis. 14. Zwei große Warteschlangen mit unterschiedlichen Synchronisationsmodi
Jetzt fällt Broker 3.

Reis. 15. Broker 3 stürzt ab und hinterlässt einen Master und einen Spiegel in jeder Warteschlange
Broker 3 ist wieder online und es werden neue Spiegel erstellt. Hauptwarteschlange A beginnt mit der Replikation vorhandener Nachrichten auf einen neuen Spiegel und während dieser Zeit ist die Warteschlange nicht verfügbar. Das Replizieren der Daten dauert zwei Stunden, was zu einer Ausfallzeit von zwei Stunden für diese Warteschlange führt!
Warteschlange B bleibt jedoch während des gesamten Zeitraums verfügbar. Sie hat einen Teil der Redundanz zugunsten der Zugänglichkeit geopfert.

Reis. 16. Die Warteschlange bleibt während der Synchronisierung nicht verfügbar
Nach zwei Stunden wird auch Warteschlange A verfügbar und kann wieder mit der Annahme von Lese- und Schreibvorgängen beginnen.
Updates
Dieses blockierende Verhalten während der Synchronisierung erschwert die Aktualisierung von Clustern mit sehr großen Warteschlangen. Irgendwann muss der Masterknoten neu gestartet werden. Dies bedeutet, dass entweder auf einen Spiegel umgeschaltet oder die Warteschlange deaktiviert werden muss, während der Server aktualisiert wird. Wenn wir uns für die Migration entscheiden, gehen Nachrichten verloren, wenn die Spiegel nicht synchronisiert sind. Wenn ein Broker getrennt wird, wird standardmäßig kein Wechsel zu einem nicht synchronisierten Spiegel durchgeführt. Dies bedeutet, dass wir keine Nachrichten verlieren, sobald der Broker wieder verfügbar ist. Der einzige Schaden besteht lediglich in der Ausfallzeit der Warteschlange. Die Verhaltensregeln beim Deaktivieren eines Brokers werden durch die Richtlinie festgelegt ha-promote-on-shutdown. Sie können einen von zwei Werten festlegen:
always= Umschalten auf nicht synchronisierte Spiegel ist aktiviertwhen-synced= nur auf einen synchronisierten Spiegel umschalten, sonst ist die Warteschlange zum Lesen und Schreiben nicht mehr verfügbar. Die Warteschlange wird wieder in Ordnung gebracht, sobald der Broker zurückkehrt.
So oder so müssen Sie bei langen Warteschlangen zwischen Datenverlust und Nichtverfügbarkeit wählen.
Wenn Verfügbarkeit die Datensicherheit verbessert
Vor einer Entscheidung muss noch eine weitere Komplikation berücksichtigt werden. Obwohl die automatische Synchronisierung besser für die Redundanz ist, welche Auswirkungen hat sie auf die Datensicherheit? Sicher, dank der besseren Redundanz ist es weniger wahrscheinlich, dass RabbitMQ vorhandene Nachrichten verliert, aber was ist mit neuen Nachrichten von Herausgebern?
Dabei ist folgendes zu beachten:
- Kann der Herausgeber einfach einen Fehler zurückgeben und der Upstream-Dienst oder Benutzer kann es später erneut versuchen?
- Kann der Herausgeber die Nachricht lokal oder in einer Datenbank speichern, um es später noch einmal zu versuchen?
Wenn ein Herausgeber eine Nachricht lediglich verwerfen kann, verbessert die Verbesserung der Zugänglichkeit tatsächlich auch die Datensicherheit.
Daher muss ein Gleichgewicht angestrebt werden, wobei die Lösung von der jeweiligen Situation abhängt.
Probleme mit ha-promote-on-failure=when-synced
Idee ha-promote-on-failure= wenn synchronisiert ist, dass wir den Wechsel auf einen nicht synchronisierten Spiegel verhindern und so Datenverlust vermeiden. Die Warteschlange ist weiterhin nicht zum Lesen oder Schreiben verfügbar. Stattdessen versuchen wir, den abgestürzten Broker mit intakten Daten wiederherzustellen, sodass er ohne Datenverlust seine Funktion als Master wieder aufnehmen kann.
Aber (und das ist ein großes Aber), wenn der Broker seine Daten verloren hat, dann haben wir ein großes Problem: Die Warteschlange ist verloren! Alle Daten sind verloren! Selbst wenn Sie Spiegel haben, die die Hauptwarteschlange größtenteils einholen, werden diese Spiegel ebenfalls verworfen.
Um einen Knoten mit demselben Namen erneut hinzuzufügen, weisen wir den Cluster an, den verlorenen Knoten zu vergessen (mit dem Befehl rabbitmqctl forget_cluster_node) und starten Sie einen neuen Broker mit demselben Hostnamen. Solange sich der Cluster an den verlorenen Knoten erinnert, erinnert er sich auch an die alte Warteschlange und die nicht synchronisierten Spiegel. Wenn einem Cluster gesagt wird, dass er einen verlorenen Knoten vergessen soll, wird auch diese Warteschlange vergessen. Jetzt müssen wir es erneut bekannt geben. Wir haben alle Daten verloren, obwohl wir Spiegel mit Teildaten hatten. Besser wäre ein Wechsel auf einen nicht synchronisierten Spiegel!
Daher ist die manuelle Synchronisierung (und das Scheitern der Synchronisierung) in Kombination mit ha-promote-on-failure=when-syncedist meiner Meinung nach ziemlich riskant. Den Dokumenten zufolge besteht diese Möglichkeit zwar aus Gründen der Datensicherheit, sie ist jedoch ein zweischneidiges Schwert.
Neugewichtung der Meister
Wie versprochen kehren wir zum Problem zurück, dass sich alle Master auf einem oder mehreren Knoten versammeln. Dies kann sogar als Ergebnis eines fortlaufenden Cluster-Upgrades passieren. In einem Cluster mit drei Knoten werden alle Hauptwarteschlangen auf einem oder zwei Knoten konzentriert.
Das Rebalancing von Mastern kann aus zwei Gründen problematisch sein:
- Es gibt keine guten Tools zur Durchführung eines Rebalancings
- Warteschlangensynchronisierung
Es gibt einen Drittanbieter für das Rebalancing , das nicht offiziell unterstützt wird. Informationen zu Plugins von Drittanbietern im RabbitMQ-Handbuch : „Das Plugin bietet einige zusätzliche Konfigurations- und Berichtstools, wird jedoch vom RabbitMQ-Team weder unterstützt noch getestet. Die Verwendung erfolgt auf eigene Gefahr.“
Es gibt einen weiteren Trick, um die Hauptwarteschlange durch HA-Richtlinien zu verschieben. Das Handbuch erwähnt dafür. Es funktioniert so:
- Entfernt alle Spiegel mithilfe einer temporären Richtlinie mit einer höheren Priorität als die vorhandene HA-Richtlinie.
- Ändert die temporäre HA-Richtlinie, um den Modus „Knoten“ zu verwenden und den Knoten anzugeben, zu dem die Master-Warteschlange migriert werden soll.
- Synchronisiert die Warteschlange für die erzwungene Migration.
- Nachdem die Migration abgeschlossen ist, wird die temporäre Richtlinie entfernt. Die anfängliche HA-Richtlinie wird in Kraft gesetzt und die erforderliche Anzahl von Spiegeln wird erstellt.
Der Nachteil besteht darin, dass dieser Ansatz möglicherweise nicht funktioniert, wenn Sie große Warteschlangen oder strenge Redundanzanforderungen haben.
Sehen wir uns nun an, wie RabbitMQ-Cluster mit Netzwerkpartitionen funktionieren.
Verbindungsverlust
Knoten in einem verteilten System sind durch Netzwerkverbindungen verbunden, und Netzwerkverbindungen können und werden getrennt. Die Häufigkeit der Ausfälle hängt von der lokalen Infrastruktur bzw. der Zuverlässigkeit der gewählten Cloud ab. Verteilte Systeme sollten in jedem Fall in der Lage sein, damit umzugehen. Wieder einmal stehen wir vor der Wahl zwischen Verfügbarkeit und Konsistenz, und die gute Nachricht ist erneut, dass RabbitMQ beides bietet (nur nicht gleichzeitig).
Mit RabbitMQ haben wir zwei Hauptoptionen:
- Split-Brain zulassen. Dies gewährleistet die Verfügbarkeit, kann jedoch zu Datenverlust führen.
- Deaktivieren Sie die logische Trennung. Kann je nach Art der Verbindung der Clients mit dem Cluster zu einem kurzfristigen Verfügbarkeitsverlust führen. Es kann auch zu einer vollständigen Nichtverfügbarkeit in einem Cluster mit zwei Knoten führen.
Aber was ist eine logische Division? Dies geschieht, wenn ein Cluster aufgrund des Verlusts von Netzwerkverbindungen in zwei Teile aufgeteilt wird. Jede Seite des Spiegels wird zu einem Master befördert, sodass jede Warteschlange am Ende mehrere Master hat.

Reis. 17. Die Hauptwarteschlange und zwei Spiegel, jeder auf einem separaten Knoten. Dann tritt ein Netzwerkfehler auf und ein Spiegel wird getrennt. Der getrennte Knoten sieht, dass die anderen beiden weggefallen sind und schiebt seine Spiegel zum Master vor. Wir haben jetzt zwei Hauptwarteschlangen, sowohl beschreibbare als auch lesbare.
Wenn Herausgeber Daten an beide Master senden, erhalten wir am Ende zwei voneinander abweichende Kopien der Warteschlange.
Die verschiedenen Modi von RabbitMQ bieten entweder Verfügbarkeit oder Konsistenz.
Ignoriermodus (Standard)
Dieser Modus bietet Zugänglichkeit. Nach dem Verlust der Kohärenz erfolgt eine logische Trennung. Sobald die Verbindung wiederhergestellt ist, muss der Administrator entscheiden, welche Partition priorisiert werden soll. Die verlierende Seite wird neu gestartet und alle auf dieser Seite gesammelten Daten gehen verloren.

Reis. 18. Drei Herausgeber sind mit drei Maklern verbunden. Intern leitet der Cluster alle Anfragen an die Hauptwarteschlange auf Broker 2 weiter.
Jetzt verlieren wir Broker 3. Er sieht, dass andere Broker ausgestiegen sind und befördert seinen Spiegel zum Master. So erfolgt die logische Trennung.

Reis. 19. Logische Teilung (Split-Brain). Die Datensätze gelangen in zwei Hauptwarteschlangen und die beiden Kopien gehen auseinander.
Die Kohärenz wird wiederhergestellt, die logische Trennung bleibt jedoch bestehen. Der Administrator muss die Verliererseite manuell auswählen. Im folgenden Fall startet der Administrator Broker 3 neu. Alle Nachrichten, die er nicht übermitteln konnte, gehen verloren.

Reis. 20. Der Administrator deaktiviert Broker 3.

Reis. 21. Der Administrator startet Broker 3 und dieser tritt dem Cluster bei. Dabei gehen alle dort verbliebenen Nachrichten verloren.
Während des Verbindungsverlusts und nach seiner Wiederherstellung waren der Cluster und diese Warteschlange zum Lesen und Schreiben verfügbar.
Autoheal-Modus
Funktioniert ähnlich wie der Ignoriermodus, mit der Ausnahme, dass der Cluster nach einer Trennung und erneuten Verbindung automatisch die verlierende Seite auswählt. Die verlierende Seite kehrt leer zum Cluster zurück und die Warteschlange verliert alle Nachrichten, die nur an diese Seite gesendet wurden.
Minderheitenmodus pausieren
Wenn wir keine logische Partitionierung zulassen möchten, besteht unsere einzige Möglichkeit darin, das Lesen und Schreiben auf der kleineren Seite nach der Clusterpartition zu verweigern. Wenn der Broker erkennt, dass die Kapazität eher gering ist, unterbricht er den Betrieb, das heißt, er schließt alle bestehenden Verbindungen und lehnt alle neuen ab. Einmal pro Sekunde wird geprüft, ob die Verbindung wiederhergestellt ist. Sobald die Verbindung wiederhergestellt ist, wird der Betrieb wieder aufgenommen und der Cluster wird verbunden.

Reis. 22. Drei Herausgeber sind mit drei Maklern verbunden. Intern leitet der Cluster alle Anfragen an die Hauptwarteschlange auf Broker 2 weiter.
Dann trennen sich die Broker 1 und 2 von Broker 3. Anstatt seinen Spiegel zum Master zu befördern, pausiert Broker 3 und ist nicht mehr verfügbar.

Reis. 23. Broker 3 unterbricht den Betrieb, trennt die Verbindung aller Clients und lehnt Verbindungsanfragen ab.
Sobald die Konnektivität wiederhergestellt ist, kehrt es zum Cluster zurück.
Sehen wir uns ein weiteres Beispiel an, bei dem sich die Hauptwarteschlange auf Broker 3 befindet.

Reis. 24. Hauptwarteschlange auf Broker 3.
Dann tritt der gleiche Kohärenzverlust auf. Broker 3 macht eine Pause, da er eher klein ist. Auf der anderen Seite sehen die Knoten, dass Broker 3 ausgefallen ist, sodass der ältere Spiegel von Broker 1 und 2 zum Master befördert wird.

Reis. 25. Wechseln Sie zu Broker 2, wenn Broker 3 nicht verfügbar ist.
Sobald die Verbindung wiederhergestellt ist, tritt Broker 3 dem Cluster bei.

Reis. 26. Der Cluster ist zum Normalbetrieb zurückgekehrt.
Wichtig ist, dass wir Konsistenz erreichen, aber auch Zugänglichkeit, wenn Wir werden die Kunden erfolgreich an den Großteil der Abteilung weiterleiten. In den meisten Situationen würde ich persönlich den Pause-Minority-Modus wählen, aber es hängt wirklich vom Einzelfall ab.
Um die Verfügbarkeit sicherzustellen, muss sichergestellt werden, dass Clients erfolgreich eine Verbindung zum Knoten herstellen können. Lassen Sie uns unsere Optionen abwägen.
Sicherstellung der Kundenkonnektivität
Wir haben mehrere Möglichkeiten, wie wir Clients nach dem Verlust der Konnektivität zum Hauptteil des Clusters oder zu funktionierenden Knoten (nach dem Ausfall eines Knotens) weiterleiten können. Bedenken wir zunächst, dass eine bestimmte Warteschlange auf einem bestimmten Knoten gehostet wird, Routing und Richtlinien jedoch auf allen Knoten repliziert werden. Clients können eine Verbindung zu jedem Knoten herstellen und werden durch internes Routing an ihr Ziel geleitet. Wenn ein Knoten jedoch angehalten wird, lehnt er Verbindungen ab, sodass Clients eine Verbindung zu einem anderen Knoten herstellen müssen. Wenn der Knoten abgefallen ist, kann er kaum etwas tun.
Unsere Optionen:
- Der Zugriff auf den Cluster erfolgt über einen Lastenausgleich, der einfach die Knoten durchläuft und die Clients versuchen, eine Verbindung erneut herzustellen, bis dies erfolgreich ist. Wenn ein Knoten ausgefallen oder angehalten ist, schlagen Verbindungsversuche mit diesem Knoten fehl, nachfolgende Versuche werden jedoch (im Round-Robin-Verfahren) an andere Server weitergeleitet. Dies eignet sich für einen kurzfristigen Verbindungsverlust oder einen ausgefallenen Server, der schnell wieder zum Laufen gebracht wird.
- Greifen Sie über den Load Balancer auf den Cluster zu und entfernen Sie angehaltene/ausgefallene Knoten aus der Liste, sobald sie erkannt werden. Wenn uns dies schnell gelingt und die Clients erneut versuchen können, eine Verbindung herzustellen, sind wir ständig verfügbar.
- Geben Sie jedem Client eine Liste aller Knoten und der Client wählt beim Verbinden zufällig einen davon aus. Wenn beim Verbindungsversuch ein Fehler auftritt, wird zum nächsten Knoten in der Liste gewechselt, bis eine Verbindung hergestellt wird.
- Entfernen Sie den Datenverkehr von einem ausgefallenen/angehaltenen Knoten mithilfe von DNS. Dies geschieht mit kleinem TTL.
Befund
RabbitMQ-Clustering hat seine eigenen Vor- und Nachteile. Die gravierendsten Nachteile sind:
- Beim Beitritt zu einem Cluster verwerfen Knoten ihre Daten.
- Das Blockieren der Synchronisierung führt dazu, dass die Warteschlange nicht verfügbar ist.
Alle schwierigen Entscheidungen ergeben sich aus diesen beiden Merkmalen der Architektur. Wenn RabbitMQ Daten über Cluster-Wiederverknüpfungen hinweg beibehalten könnte, wäre die Synchronisierung schneller. Wenn es eine nicht blockierende Synchronisierung ermöglichen würde, würde es große Warteschlangen besser unterstützen. Die Behebung dieser beiden Probleme würde die Leistung von RabbitMQ als fehlertolerante und hochverfügbare Messaging-Technologie erheblich verbessern. In den folgenden Situationen würde ich RabbitMQ mit Clustering nur ungern empfehlen:
- Unzuverlässiges Netzwerk.
- Unzuverlässiger Speicher.
- Sehr lange Warteschlangen.
Bezüglich der Hochverfügbarkeitseinstellungen sollten Sie Folgendes berücksichtigen:
ha-promote-on-failure=alwaysha-sync-mode=manualcluster_partition_handling=ignore(oderautoheal)- persistente Nachrichten
- Stellen Sie sicher, dass Clients eine Verbindung zum aktiven Knoten herstellen, wenn ein Knoten ausfällt
Berücksichtigen Sie aus Gründen der Konsistenz (Datensicherheit) die folgenden Einstellungen:
- Bestätigungen des Herausgebers und manuelle Bestätigungen auf der Verbraucherseite
ha-promote-on-failure=when-synced, wenn die Herausgeber es später noch einmal versuchen können und wenn Sie über einen sehr zuverlässigen Speicher verfügen! Andernfalls legen Sie es=always.ha-sync-mode=automatic(bei großen inaktiven Warteschlangen kann jedoch der manuelle Modus erforderlich sein; bedenken Sie auch, ob die Nichtverfügbarkeit zum Verlust von Nachrichten führt)- Minderheitenmodus pausieren
- persistente Nachrichten
Wir haben noch nicht alle Probleme der Fehlertoleranz und Hochverfügbarkeit behandelt. Beispielsweise erfahren Sie, wie Sie Verwaltungsvorgänge (wie etwa Rolling Updates) sicher durchführen. Wir müssen auch über die Föderation und das Shovel-Plugin sprechen.
Wenn ich noch etwas vergessen habe, lassen Sie es mich bitte wissen.
Siehe auch meine , wo ich mithilfe von Docker und Blockade ein RabbitMQ-Cluster verwüste, um einige der in diesem Artikel beschriebenen Szenarien zum Nachrichtenverlust zu testen.
Vorherige Artikel in der Reihe:
Nr. 1 -
Nr. 2 -
Nr. 3 -
Source: habr.com
