RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit

В letzter Artikel Wir haben uns das RabbitMQ-Clustering im Hinblick auf Fehlertoleranz und hohe Verfügbarkeit angesehen. Lassen Sie uns nun tiefer in Apache Kafka eintauchen.

Hier ist die Replikationseinheit die Partition. Jedes Thema besteht aus einem oder mehreren Abschnitten. Jeder Abschnitt hat einen Leiter mit oder ohne Anhänger. Beim Erstellen eines Themas geben Sie die Anzahl der Partitionen und den Replikationskoeffizienten an. Der übliche Wert ist 3, was drei Replikate bedeutet: einen Anführer und zwei Anhänger.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 1. Vier Abschnitte werden auf drei Makler verteilt

Alle Lese- und Schreibanfragen gehen an den Leiter. Follower senden regelmäßig Anfragen an den Leiter, um die neuesten Nachrichten zu erhalten. Verbraucher wenden sich nie an Follower; Letztere dienen nur der Redundanz und Fehlertoleranz.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit

Partitionsfehler

Wenn ein Makler scheitert, scheitern oft auch die Leiter mehrerer Sektionen. In jedem von ihnen wird ein Anhänger eines anderen Knotens zum Anführer. Tatsächlich ist dies nicht immer der Fall, da der Synchronisationsfaktor auch Einfluss darauf hat: ob synchronisierte Follower vorhanden sind und wenn nicht, ob der Wechsel zu einem unsynchronisierten Replikat zulässig ist. Aber lassen Sie uns die Dinge vorerst nicht verkomplizieren.

Broker 3 verlässt das Netzwerk und bei Broker 2 wird ein neuer Leiter für Abschnitt 2 gewählt.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 2. Broker 3 stirbt und sein Anhänger auf Broker 2 wird zum neuen Anführer von Partition 2 gewählt

Dann verlässt Makler 1 und Abschnitt 1 verliert auch seinen Anführer, dessen Rolle auf Makler 2 übergeht.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 3. Es ist noch ein Broker übrig. Alle Führungskräfte sind bei einem Broker ohne Redundanz

Wenn Broker 1 wieder online geht, fügt er vier Follower hinzu und sorgt so für eine gewisse Redundanz für jede Partition. Aber alle Anführer blieben immer noch auf Broker 2.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 4. Leader bleiben auf Broker 2

Wenn Broker 3 startet, sind wir wieder bei drei Replikaten pro Partition. Aber alle Anführer sind immer noch auf Broker 2.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 5. Unausgewogene Platzierung der Leiter nach der Wiederherstellung der Makler 1 und 3

Kafka verfügt über ein Tool für eine bessere Neuausrichtung von Führungskräften als RabbitMQ. Dort mussten Sie ein Plugin oder Skript eines Drittanbieters verwenden, das die Richtlinien für die Migration des Masterknotens änderte, indem es die Redundanz während der Migration reduzierte. Darüber hinaus mussten wir bei großen Warteschlangen die Nichtverfügbarkeit während der Synchronisierung in Kauf nehmen.

Kafka hat für die Führungsrolle das Konzept der „bevorzugten Repliken“ entwickelt. Wenn Themenpartitionen erstellt werden, versucht Kafka, die Anführer gleichmäßig auf die Knoten zu verteilen, und markiert die ersten Anführer als bevorzugt. Im Laufe der Zeit kann es aufgrund von Serverneustarts, Ausfällen und Verbindungsausfällen dazu kommen, dass Führungskräfte auf anderen Knoten landen, wie im oben beschriebenen Extremfall.

Um dies zu beheben, bietet Kafka zwei Möglichkeiten:

  • Option auto.leader.rebalance.enable=true ermöglicht es dem Controller-Knoten, Anführer automatisch wieder den bevorzugten Replikaten zuzuordnen und dadurch eine gleichmäßige Verteilung wiederherzustellen.
  • Der Administrator kann das Skript ausführen kafka-preferred-replica-election.sh zur manuellen Neuzuweisung.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 6. Replikate nach der Neuausrichtung

Dies war eine vereinfachte Version des Scheiterns, aber die Realität ist komplexer, obwohl es hier nichts allzu Kompliziertes gibt. Es kommt auf synchronisierte Replikate (In-Sync Replicas, ISR) an.

Synchronisierte Replikate (ISR)

Ein ISR ist eine Reihe von Replikaten einer Partition, die als „synchronisiert“ (synchron) gilt. Es gibt einen Anführer, aber möglicherweise keine Anhänger. Ein Follower gilt als synchronisiert, wenn er vor Ablauf des Intervalls exakte Kopien aller Nachrichten des Anführers erstellt hat Replica.lag.time.max.ms.

Ein Follower wird aus dem ISR-Satz entfernt, wenn er:

  • Es wurde keine Anfrage zur Auswahl des Intervalls gestellt Replica.lag.time.max.ms (Vermutlich tot)
  • Die Aktualisierung konnte während des Intervalls nicht durchgeführt werden Replica.lag.time.max.ms (gilt als langsam)

Follower stellen in dem Intervall Sampling-Anfragen Replikat.fetch.wait.max.ms, der Standardwert ist 500 ms.

Um den Zweck von ISR klar zu erklären, müssen wir uns Bestätigungen des Herstellers und einige Fehlerszenarien ansehen. Hersteller können wählen, wann der Broker die Bestätigung sendet:

  • acks=0, Bestätigung wird nicht gesendet
  • acks=1, die Bestätigung wird gesendet, nachdem der Leiter eine Nachricht in sein lokales Protokoll geschrieben hat
  • acks=all, die Bestätigung wird gesendet, nachdem alle Replikate im ISR die Nachricht in die lokalen Protokolle geschrieben haben

Wenn der ISR eine Nachricht gespeichert hat, ist sie in der Kafka-Terminologie „festgeschrieben“. Acks=all ist die sicherste Option, führt aber auch zu zusätzlicher Verzögerung. Schauen wir uns zwei Beispiele für Fehler an und wie die verschiedenen „Acks“-Optionen mit dem ISR-Konzept interagieren.

Acks=1 und ISR

In diesem Beispiel werden wir sehen, dass, wenn der Anführer nicht darauf wartet, dass jede Nachricht von allen Followern gespeichert wird, ein Datenverlust möglich ist, wenn der Anführer ausfällt. Die Navigation zu einem nicht synchronisierten Follower kann per Einstellung aktiviert oder deaktiviert werden unclean.leader.election.enable.

In diesem Beispiel hat der Hersteller den Wert acks=1. Der Abschnitt ist auf alle drei Broker verteilt. Broker 3 liegt im Rückstand, er hat sich vor acht Sekunden mit dem Spitzenreiter synchronisiert und liegt nun 7456 Nachrichten zurück. Broker 1 lag nur eine Sekunde zurück. Unser Produzent sendet eine Nachricht und erhält schnell eine Bestätigung zurück, ohne den Overhead durch langsame oder tote Follower, auf die der Anführer nicht wartet.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 7. ISR mit drei Repliken

Broker 2 fällt aus und der Produzent erhält einen Verbindungsfehler. Nachdem die Führung an Makler 1 übergegangen ist, verlieren wir 123 Nachrichten. Der Follower auf Broker 1 war Teil des ISR, war jedoch nicht vollständig mit dem Leader synchronisiert, als dieser fiel.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 8. Bei einem Absturz gehen Nachrichten verloren

In der Konfiguration Bootstrap.server Der Hersteller hat mehrere Makler aufgelistet und kann einen anderen Makler fragen, wer der neue Bereichsleiter ist. Anschließend baut er eine Verbindung zu Broker 1 auf und sendet weiterhin Nachrichten.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 9. Der Nachrichtenversand wird nach einer kurzen Pause fortgesetzt

Broker 3 liegt noch weiter zurück. Es stellt Abrufanfragen, kann aber nicht synchronisiert werden. Dies kann auf eine langsame Netzwerkverbindung zwischen Brokern, Speicherprobleme usw. zurückzuführen sein. Es wird aus dem ISR entfernt. Jetzt besteht der ISR aus einer Replik – dem Anführer! Der Hersteller sendet weiterhin Nachrichten und erhält Bestätigungen.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 10. Follower auf Broker 3 wird aus dem ISR entfernt

Broker 1 fällt aus und die Führungsrolle geht an Broker 3 über, mit dem Verlust von 15286 Nachrichten! Der Hersteller erhält eine Verbindungsfehlermeldung. Der Übergang zu einer Führungspersönlichkeit außerhalb des ISR war nur aufgrund des Setting möglich unclean.leader.election.enable=true. Wenn es installiert ist falsch, dann würde der Übergang nicht stattfinden und alle Lese- und Schreibanforderungen würden abgelehnt. In diesem Fall warten wir darauf, dass Broker 1 mit seinen intakten Daten in der Replik zurückkehrt, die wiederum die Führung übernimmt.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 11. Broker 1 fällt. Wenn ein Fehler auftritt, geht eine große Anzahl von Nachrichten verloren

Der Produzent stellt eine Verbindung zum letzten Makler her und sieht, dass dieser nun der Leiter der Sektion ist. Er beginnt, Nachrichten an Broker 3 zu senden.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 12. Nach einer kurzen Pause werden die Nachrichten erneut an Abschnitt 0 gesendet

Wir sahen, dass der Hersteller, abgesehen von kurzen Unterbrechungen, um neue Kontakte zu knüpfen und nach einem neuen Leiter zu suchen, ständig Nachrichten sendete. Diese Konfiguration stellt die Verfügbarkeit auf Kosten der Konsistenz (Datensicherheit) sicher. Kafka verlor Tausende von Nachrichten, akzeptierte aber weiterhin neue Schreibvorgänge.

Acks=all und ISR

Wiederholen wir dieses Szenario noch einmal, aber mit acks=alle. Broker 3 hat eine durchschnittliche Latenz von vier Sekunden. Der Hersteller sendet eine Nachricht mit acks=alle, und erhält jetzt keine schnelle Antwort. Der Leiter wartet darauf, dass die Nachricht von allen Replikaten im ISR gespeichert wird.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 13. ISR mit drei Repliken. Einer ist langsam, was zu Verzögerungen bei der Aufnahme führt

Nach vier Sekunden zusätzlicher Verzögerung sendet Broker 2 eine Bestätigung. Alle Replikate sind jetzt vollständig aktualisiert.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 14. Alle Replikate speichern Nachrichten und senden eine Bestätigung

Broker 3 fällt nun weiter zurück und wird aus dem ISR entfernt. Die Latenz wird erheblich reduziert, da im ISR keine langsamen Replikate mehr vorhanden sind. Broker 2 wartet jetzt nur noch auf Broker 1 und dieser hat eine durchschnittliche Verzögerung von 500 ms.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 15. Das Replikat auf Broker 3 wird aus dem ISR entfernt

Dann fällt Makler 2 und die Führung geht ohne Nachrichtenverlust an Makler 1 über.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 16. Broker 2 fällt

Der Hersteller findet einen neuen Anführer und beginnt, ihm Nachrichten zu senden. Die Latenz wird weiter reduziert, da der ISR nun aus einem Replikat besteht! Daher die Option acks=alle fügt keine Redundanz hinzu.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 17. Replikat auf Broker 1 übernimmt die Führung, ohne Nachrichten zu verlieren

Dann stürzt Broker 1 ab und der Lead geht an Broker 3 mit einem Verlust von 14238 Nachrichten!

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 18. Der Tod von Broker 1 und der Führungswechsel mit unsauberer Einstellung führen zu umfangreichem Datenverlust

Wir konnten die Option nicht installieren unclean.leader.election.enable in die Bedeutung was immer dies auch sein sollte.. Standardmäßig ist es gleich falsch. Einstellungen acks=alle с unclean.leader.election.enable=true Bietet Zugänglichkeit mit etwas zusätzlicher Datensicherheit. Aber wie Sie sehen, können wir immer noch Nachrichten verlieren.

Was aber, wenn wir die Datensicherheit erhöhen wollen? Du kannst Geben unclean.leader.election.enable = falseDies schützt uns jedoch nicht unbedingt vor Datenverlust. Wenn der Anführer hart gestürzt ist und die Daten mitgenommen hat, gehen die Nachrichten immer noch verloren und die Verfügbarkeit geht verloren, bis der Administrator die Situation wiederherstellt.

Es ist besser, sicherzustellen, dass alle Nachrichten redundant sind, und andernfalls die Aufzeichnung zu verwerfen. Dann ist zumindest aus Sicht des Brokers ein Datenverlust nur bei zwei oder mehr gleichzeitigen Ausfällen möglich.

Acks=all, min.insync.replicas und ISR

Mit Themenkonfiguration min.insync.replicas Wir erhöhen das Niveau der Datensicherheit. Gehen wir den letzten Teil des vorherigen Szenarios noch einmal durch, diesmal jedoch mit min.insync.replicas=2.

Broker 2 hat also einen Replikat-Leader und der Follower auf Broker 3 wird aus dem ISR entfernt.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 19. ISR aus zwei Repliken

Broker 2 fällt und die Führung geht ohne Nachrichtenverlust an Broker 1 über. Aber jetzt besteht der ISR nur noch aus einer Replik. Dies entspricht nicht der Mindestanzahl zum Empfangen von Datensätzen und daher antwortet der Broker auf den Schreibversuch mit einem Fehler NotEnoughReplicas.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 20. Die Anzahl der ISRs ist um eins niedriger als in min.insync.replicas angegeben

Bei dieser Konfiguration geht die Verfügbarkeit zugunsten der Konsistenz verloren. Bevor wir eine Nachricht bestätigen, stellen wir sicher, dass sie auf mindestens zwei Replikate geschrieben wird. Das gibt dem Hersteller deutlich mehr Vertrauen. Hier ist ein Nachrichtenverlust nur dann möglich, wenn zwei Replikate in einem kurzen Zeitraum gleichzeitig ausfallen, bis die Nachricht auf einen zusätzlichen Follower repliziert wird, was unwahrscheinlich ist. Aber wenn Sie extrem paranoid sind, können Sie den Replikationsfaktor auf 5 setzen und min.insync.replicas um 3. Hier müssen drei Broker gleichzeitig fallen, um den Rekord zu verlieren! Diese Zuverlässigkeit bezahlen Sie natürlich mit zusätzlicher Latenz.

Wenn Zugänglichkeit für die Datensicherheit erforderlich ist

Wie in Fall mit RabbitMQManchmal ist die Zugänglichkeit für die Datensicherheit erforderlich. Folgendes müssen Sie bedenken:

  • Kann der Herausgeber einfach einen Fehler zurückgeben und den Upstream-Dienst oder Benutzer veranlassen, es später erneut zu versuchen?
  • Kann der Herausgeber die Nachricht lokal oder in einer Datenbank speichern, um es später noch einmal zu versuchen?

Wenn die Antwort „Nein“ lautet, verbessert die Optimierung der Verfügbarkeit die Datensicherheit. Sie verlieren weniger Daten, wenn Sie die Verfügbarkeit statt der Nichtaufzeichnung wählen. Es kommt also darauf an, ein Gleichgewicht zu finden, und die Entscheidung hängt von der konkreten Situation ab.

Die Bedeutung von ISR

Mit der ISR-Suite können Sie das optimale Gleichgewicht zwischen Datensicherheit und Latenz wählen. Stellen Sie beispielsweise die Verfügbarkeit im Falle eines Ausfalls der meisten Replikate sicher und minimieren Sie so die Auswirkungen von toten oder langsamen Replikaten im Hinblick auf die Latenz.

Die Bedeutung wählen wir selbst Replica.lag.time.max.ms nach Ihren Bedürfnissen. Im Wesentlichen gibt dieser Parameter an, wie viel Verzögerung wir wann bereit sind zu akzeptieren acks=alle. Der Standardwert beträgt zehn Sekunden. Wenn Ihnen das zu lang ist, können Sie es verkürzen. Dann wird die Häufigkeit der Änderungen im ISR zunehmen, da Follower häufiger entfernt und hinzugefügt werden.

RabbitMQ ist einfach eine Reihe von Spiegeln, die repliziert werden müssen. Langsame Spiegel führen zu zusätzlicher Latenz, und tote Spiegel können warten, bis die Pakete, die die Verfügbarkeit jedes Knotens prüfen (Netto-Tick), antworten. ISR ist eine interessante Möglichkeit, diese Latenzprobleme zu vermeiden. Aber wir laufen Gefahr, Redundanz zu verlieren, da der ISR nur auf den Marktführer schrumpfen kann. Um dieses Risiko zu vermeiden, verwenden Sie die Einstellung min.insync.replicas.

Client-Verbindungsgarantie

In der Einstellung des Bootstrap.server Produzent und Verbraucher können mehrere Broker für die Verbindung von Clients angeben. Die Idee besteht darin, dass beim Ausfall eines Knotens mehrere Ersatzknoten übrig bleiben, mit denen der Client eine Verbindung herstellen kann. Dabei handelt es sich nicht unbedingt um Abschnittsleiter, sondern lediglich um ein Sprungbrett für den ersten Einstieg. Der Client kann ihn fragen, welcher Knoten den Leader der Lese-/Schreibpartition hostet.

In RabbitMQ können Clients eine Verbindung zu jedem Knoten herstellen, und das interne Routing sendet die Anfrage dorthin, wo sie hin muss. Das bedeutet, dass Sie einen Load Balancer vor RabbitMQ installieren können. Kafka erfordert, dass Clients eine Verbindung zu dem Knoten herstellen, der den entsprechenden Partitionsleader hostet. In einer solchen Situation können Sie keinen Load Balancer installieren. Aufführen Bootstrap.server Es ist wichtig, dass Clients nach einem Fehler auf die richtigen Knoten zugreifen und diese finden können.

Kafka-Konsensarchitektur

Bisher haben wir nicht darüber nachgedacht, wie der Cluster vom Sturz des Maklers erfährt und wie ein neuer Anführer gewählt wird. Um zu verstehen, wie Kafka mit Netzwerkpartitionen arbeitet, müssen Sie zunächst die Konsensarchitektur verstehen.

Jeder Kafka-Cluster wird zusammen mit einem Zookeeper-Cluster bereitgestellt, einem verteilten Konsensdienst, der es dem System ermöglicht, einen Konsens über einen bestimmten Zustand zu erzielen, wobei Konsistenz Vorrang vor Verfügbarkeit hat. Zur Genehmigung von Lese- und Schreibvorgängen ist die Zustimmung der Mehrheit der Zookeeper-Knoten erforderlich.

Zookeeper speichert den Status des Clusters:

  • Liste der Themen, Abschnitte, Konfiguration, aktuelle Leader-Replikate, bevorzugte Replikate.
  • Cluster-Mitglieder. Jeder Broker pingt den Zookeeper-Cluster. Wenn innerhalb eines bestimmten Zeitraums kein Ping empfangen wird, zeichnet Zookeeper den Broker als nicht verfügbar auf.
  • Auswahl der Haupt- und Ersatzknoten für den Controller.

Der Controller-Knoten ist einer der Kafka-Broker, der für die Wahl der Replikatführer verantwortlich ist. Zookeeper sendet Benachrichtigungen über Clustermitgliedschaft und Themenänderungen an den Controller, und der Controller muss auf diese Änderungen reagieren.

Nehmen wir zum Beispiel ein neues Thema mit zehn Partitionen und einem Replikationsfaktor von 3. Der Controller muss für jede Partition einen Anführer wählen und versuchen, die Anführer optimal auf die Broker zu verteilen.

Für jeden Abschnittscontroller:

  • aktualisiert Informationen in Zookeeper über ISR und Leader;
  • Sendet einen LeaderAndISRCommand an jeden Broker, der eine Replik dieser Partition hostet, und informiert die Broker über den ISR und den Leader.

Wenn ein Makler mit einem Anführer ausfällt, sendet Zookeeper eine Benachrichtigung an den Controller und wählt einen neuen Anführer. Auch hier aktualisiert der Controller zunächst Zookeeper und sendet dann einen Befehl an jeden Broker, um ihn über den Führungswechsel zu informieren.

Jeder Leiter ist für die Rekrutierung von ISRs verantwortlich. Einstellungen Replica.lag.time.max.ms bestimmt, wer dort eintreten wird. Wenn sich der ISR ändert, übermittelt der Leiter neue Informationen an Zookeeper.

Zookeeper ist stets über alle Änderungen informiert, sodass im Falle eines Ausfalls die Geschäftsführung reibungslos auf einen neuen Leiter übergeht.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 21. Kafka-Konsens

Replikationsprotokoll

Wenn Sie die Details der Replikation verstehen, können Sie potenzielle Datenverlustszenarien besser verstehen.

Stichprobenabfragen, Log End Offset (LEO) und Highwater Mark (HW)

Wir haben berücksichtigt, dass Follower regelmäßig Abrufanfragen an den Anführer senden. Das Standardintervall beträgt 500 ms. Der Unterschied zu RabbitMQ besteht darin, dass die Replikation bei RabbitMQ nicht vom Warteschlangenspiegel, sondern vom Master initiiert wird. Der Master überträgt Änderungen an die Spiegel.

Der Leader und alle Follower speichern den Log End Offset (LEO) und die Highwater (HW)-Beschriftung. Die LEO-Markierung speichert den Offset der letzten Nachricht im lokalen Replikat und die HW speichert den Offset des letzten Commits. Denken Sie daran, dass die Nachricht für den Commit-Status in allen ISR-Replikaten bestehen bleiben muss. Damit liegt LEO in der Regel leicht vor HW.

Wenn der Leiter eine Nachricht erhält, speichert er sie lokal. Der Follower stellt eine Abrufanfrage, indem er seinen LEO übermittelt. Der Anführer sendet dann ausgehend von diesem LEO einen Stapel von Nachrichten und übermittelt auch die aktuelle HW. Wenn der Leader die Information erhält, dass alle Replikate die Nachricht am angegebenen Offset gespeichert haben, verschiebt er die HW-Markierung. Nur der Anführer kann das HW verschieben, sodass alle Follower den aktuellen Wert in den Antworten auf ihre Anfrage kennen. Dies bedeutet, dass die Follower möglicherweise sowohl in Bezug auf die Botschaft als auch in Bezug auf das HW-Wissen hinter dem Leader zurückbleiben. Verbraucher erhalten Nachrichten nur bis zur aktuellen HW.

Beachten Sie, dass „persistent“ bedeutet, dass es in den Speicher und nicht auf die Festplatte geschrieben wird. Aus Leistungsgründen synchronisiert Kafka in einem bestimmten Intervall die Festplatte. RabbitMQ verfügt ebenfalls über ein solches Intervall, sendet jedoch erst dann eine Bestätigung an den Herausgeber, wenn der Master und alle Spiegel die Nachricht auf die Festplatte geschrieben haben. Aus Leistungsgründen haben die Kafka-Entwickler beschlossen, eine Bestätigung zu senden, sobald die Nachricht in den Speicher geschrieben wird. Kafka geht davon aus, dass Redundanz das Risiko ausgleicht, bestätigte Nachrichten kurzzeitig nur im Speicher zu speichern.

Führungsversagen

Wenn ein Anführer fällt, benachrichtigt Zookeeper den Controller und wählt eine neue Anführerreplik aus. Der neue Anführer setzt laut seinem LEO eine neue HW-Marke. Follower erhalten dann Informationen über den neuen Anführer. Je nach Kafka-Version wählt der Anhänger eines von zwei Szenarios:

  1. Das lokale Protokoll wird auf eine bekannte Hardware gekürzt und eine Anfrage für Nachrichten nach dieser Markierung an den neuen Leiter gesendet.
  2. Sendet eine Anfrage an den Anführer, um die HW zum Zeitpunkt seiner Wahl zum Anführer herauszufinden, und schneidet dann das Protokoll auf diesen Offset ab. Anschließend werden ab diesem Offset regelmäßige Abrufanforderungen gestellt.

Ein Follower muss das Protokoll möglicherweise aus folgenden Gründen kürzen:

  • Wenn ein Anführer versagt, gewinnt der erste bei Zookeeper registrierte Follower im ISR-Set die Wahl und wird zum Anführer. Obwohl alle Follower auf ISR als „synchron“ gelten, haben sie möglicherweise nicht Kopien aller Nachrichten vom ehemaligen Anführer erhalten. Es ist durchaus möglich, dass der vorgestellte Follower nicht über die aktuellste Kopie verfügt. Kafka stellt sicher, dass es keine Abweichungen zwischen den Repliken gibt. Um Diskrepanzen zu vermeiden, muss daher jeder Follower sein Protokoll auf den HW-Wert des neuen Leaders zum Zeitpunkt seiner Wahl kürzen. Dies ist ein weiterer Grund für die Einstellung acks=alle so wichtig für die Konsistenz.
  • Nachrichten werden regelmäßig auf die Festplatte geschrieben. Wenn alle Cluster-Knoten gleichzeitig ausfallen, werden Replikate mit unterschiedlichen Offsets auf den Festplatten gespeichert. Wenn die Makler wieder online gehen, ist es möglich, dass der neu gewählte Anführer hinter seinen Anhängern steht, weil er vor den anderen auf der Festplatte gespeichert wurde.

Wiedersehen mit dem Cluster

Beim erneuten Beitritt zum Cluster machen die Replikate das Gleiche wie beim Ausfall eines Anführers: Sie überprüfen die Replik des Anführers und kürzen ihr Protokoll auf dessen Hardware (zum Zeitpunkt der Wahl). Im Vergleich dazu behandelt RabbitMQ wiedervereinigte Knoten gleichermaßen als völlig neu. In beiden Fällen verwirft der Broker jeden vorhandenen Status. Wenn die automatische Synchronisierung verwendet wird, muss der Master absolut alle aktuellen Inhalte auf den neuen Spiegel replizieren, und zwar nach dem Prinzip „die ganze Welt warten lassen“. Während dieses Vorgangs akzeptiert der Master keine Lese- oder Schreibvorgänge. Dieser Ansatz führt zu Problemen in großen Warteschlangen.

Kafka ist ein verteiltes Protokoll und speichert im Allgemeinen mehr Nachrichten als eine RabbitMQ-Warteschlange, bei der Daten nach dem Lesen aus der Warteschlange entfernt werden. Aktive Warteschlangen sollten relativ klein bleiben. Aber Kafka ist ein Protokoll mit einer eigenen Aufbewahrungsrichtlinie, die einen Zeitraum von Tagen oder Wochen festlegen kann. Der Ansatz der Warteschlangenblockierung und der vollständigen Synchronisierung ist für ein verteiltes Protokoll absolut inakzeptabel. Stattdessen kürzen Kafka-Anhänger ihr Protokoll einfach auf die HW des Anführers (zum Zeitpunkt seiner Wahl), wenn ihre Kopie vor dem Anführer liegt. Im wahrscheinlicheren Fall, wenn der Follower im Rückstand ist, beginnt er einfach, Abrufanfragen zu stellen, beginnend mit seinem aktuellen LEO.

Neue oder wieder beigetretene Follower beginnen außerhalb des ISR und nehmen nicht an Commits teil. Sie arbeiten einfach mit der Gruppe zusammen und empfangen Nachrichten so schnell wie möglich, bis sie den Anführer einholen und das ISR betreten. Es gibt keine Bindung und Sie müssen nicht alle Ihre Daten wegwerfen.

Verbindungsverlust

Kafka verfügt über mehr Komponenten als RabbitMQ und verfügt daher über ein komplexeres Verhalten, wenn die Verbindung zum Cluster getrennt wird. Aber Kafka wurde ursprünglich für Cluster entwickelt, daher sind die Lösungen sehr gut durchdacht.

Im Folgenden sind mehrere Szenarien für Verbindungsfehler aufgeführt:

  • Szenario 1: Der Follower sieht den Anführer nicht, aber immer noch den Zookeeper.
  • Szenario 2: Der Anführer sieht keine Follower, sieht aber dennoch Zookeeper.
  • Szenario 3: Der Follower sieht den Anführer, aber nicht den Zookeeper.
  • Szenario 4: Der Anführer sieht die Follower, aber nicht den Zookeeper.
  • Szenario 5: Der Follower ist vollständig von den anderen Kafka-Knoten und Zookeeper getrennt.
  • Szenario 6: Der Anführer ist vollständig von den anderen Kafka-Knoten und Zookeeper getrennt.
  • Szenario 7: Der Kafka-Controllerknoten kann keinen anderen Kafka-Knoten sehen.
  • Szenario 8: Der Kafka-Controller erkennt Zookeeper nicht.

Jedes Szenario hat sein eigenes Verhalten.

Szenario 1: Follower sieht den Anführer nicht, sieht aber immer noch Zookeeper

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 22. Szenario 1: ISR von drei Replikaten

Der Verbindungsfehler trennt Broker 3 von den Brokern 1 und 2, nicht jedoch von Zookeeper. Broker 3 kann keine Abrufanfragen mehr senden. Nachdem die Zeit vergangen ist Replica.lag.time.max.ms Es wird aus dem ISR entfernt und nimmt nicht an Nachrichtenfestschreibungen teil. Sobald die Konnektivität wiederhergestellt ist, nimmt es die Abrufanfragen wieder auf und tritt dem ISR bei, wenn es den Anführer einholt. Zookeeper empfängt weiterhin Pings und geht davon aus, dass der Broker gesund und munter ist.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 23. Szenario 1: Der Broker wird aus dem ISR entfernt, wenn innerhalb des Intervalls „replica.lag.time.max.ms“ keine Abrufanforderung von ihm empfangen wird

Es gibt keine Split-Brain- oder Node-Suspension wie in RabbitMQ. Stattdessen wird die Redundanz reduziert.

Szenario 2: Leader sieht keine Follower, sieht aber immer noch Zookeeper

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 24. Szenario 2. Anführer und zwei Anhänger

Eine Unterbrechung der Netzwerkkonnektivität trennt den Anführer von den Followern, aber der Broker kann Zookeeper weiterhin sehen. Wie im ersten Szenario schrumpft der ISR, dieses Mal jedoch nur für den Anführer, da alle Follower keine Abrufanfragen mehr senden. Auch hier gibt es keine logische Trennung. Stattdessen kommt es zu einem Redundanzverlust für neue Nachrichten, bis die Konnektivität wiederhergestellt ist. Zookeeper erhält weiterhin Pings und glaubt, dass der Broker gesund und munter ist.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 25. Szenario 2. ISR ist nur noch auf den Spitzenreiter geschrumpft

Szenario 3. Der Follower sieht den Anführer, aber nicht den Zookeeper

Der Follower ist vom Zookeeper getrennt, nicht jedoch vom Broker mit dem Leader. Infolgedessen stellt der Follower weiterhin Abrufanfragen und ist Mitglied des ISR. Zookeeper empfängt keine Pings mehr und registriert keinen Broker-Absturz, aber da es sich nur um einen Follower handelt, gibt es nach der Wiederherstellung keine Konsequenzen.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 26. Szenario 3: Der Follower sendet weiterhin Abrufanfragen an den Anführer

Szenario 4. Leader sieht Follower, aber Zookeeper nicht

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 27. Szenario 4. Anführer und zwei Anhänger

Der Anführer ist vom Zookeeper getrennt, nicht jedoch von den Maklern mit Anhängern.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 28. Szenario 4: Anführer vom Zookeeper isoliert

Nach einiger Zeit registriert Zookeeper einen Brokerfehler und benachrichtigt den Controller darüber. Er wird unter seinen Anhängern einen neuen Anführer wählen. Der ursprüngliche Anführer wird jedoch weiterhin denken, dass er der Anführer ist, und weiterhin Einträge von annehmen acks=1. Follower senden ihm keine Abrufanfragen mehr, daher wird er sie für tot halten und versuchen, den ISR auf sich selbst zu reduzieren. Da es jedoch keine Verbindung zu Zookeeper hat, ist dies nicht möglich und es werden dann keine weiteren Einträge mehr akzeptiert.

Nachrichten acks=alle erhält keine Bestätigung, da der ISR zunächst alle Replikate aktiviert und die Nachrichten diese nicht erreichen. Wenn der ursprüngliche Anführer versucht, sie aus dem ISR zu entfernen, ist er dazu nicht in der Lage und nimmt überhaupt keine Nachrichten mehr an.

Die Kunden bemerken den Wechsel des Leiters bald und beginnen, Datensätze an den neuen Server zu senden. Sobald das Netzwerk wiederhergestellt ist, erkennt der ursprüngliche Anführer, dass es kein Anführer mehr ist, und kürzt sein Protokoll auf den HW-Wert, den der neue Anführer zum Zeitpunkt des Fehlers hatte, um Protokollabweichungen zu vermeiden. Anschließend werden Abrufanfragen an den neuen Leiter gesendet. Alle Datensätze des ursprünglichen Leaders, die nicht auf den neuen Leader repliziert werden, gehen verloren. Das heißt, Nachrichten, die vom ursprünglichen Leiter in den wenigen Sekunden, in denen zwei Leiter arbeiteten, nicht bestätigt wurden, gehen verloren.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 29. Szenario 4. Der Leader auf Broker 1 wird nach der Wiederherstellung des Netzwerks zum Follower

Szenario 5: Der Follower ist vollständig von den anderen Kafka-Knoten und Zookeeper getrennt

Der Follower ist vollständig von den anderen Kafka-Knoten und Zookeeper isoliert. Er entfernt sich einfach aus dem ISR, bis das Netzwerk wiederhergestellt ist, und schließt sich dann den anderen an.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 30. Szenario 5: Isolierter Follower wird aus ISR entfernt

Szenario 6: Der Anführer ist vollständig von den anderen Kafka-Knoten und Zookeeper getrennt

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 31. Szenario 6. Anführer und zwei Anhänger

Der Anführer ist völlig isoliert von seinen Anhängern, dem Kontrolleur und Tierpfleger. Für einen kurzen Zeitraum werden weiterhin Einträge von angenommen acks=1.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 32. Szenario 6: Isolierung des Anführers von anderen Kafka- und Zookeeper-Knoten

Keine Anfragen nach Ablauf erhalten Replica.lag.time.max.ms, wird es versuchen, den ISR auf sich selbst zu verkleinern, ist aber nicht in der Lage, dies zu tun, da keine Kommunikation mit Zookeeper besteht, und akzeptiert dann keine Schreibvorgänge mehr.

In der Zwischenzeit markiert Zookeeper den isolierten Makler als tot und der Controller wählt einen neuen Anführer.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 33. Szenario 6. Zwei Anführer

Der ursprüngliche Anführer akzeptiert möglicherweise einige Sekunden lang Eingaben, nimmt dann aber keine Nachrichten mehr an. Clients werden alle 60 Sekunden mit den neuesten Metadaten aktualisiert. Sie werden über den Leiterwechsel informiert und beginnen, Einträge an den neuen Leiter zu senden.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 34. Szenario 6: Hersteller wechseln zu einem neuen Marktführer

Alle bestätigten Eingaben des ursprünglichen Leiters seit dem Verbindungsverlust gehen verloren. Sobald das Netzwerk wiederhergestellt ist, erkennt der ursprüngliche Anführer über Zookeeper, dass er nicht mehr der Anführer ist. Dann kürzt es sein Protokoll auf die HW des neuen Anführers zum Zeitpunkt der Wahl und beginnt, Anfragen als Follower zu senden.

RabbitMQ vs. Kafka: Fehlertoleranz und hohe Verfügbarkeit
Reis. 35. Szenario 6: Der ursprüngliche Anführer wird zum Follower, nachdem die Netzwerkkonnektivität wiederhergestellt wurde

In dieser Situation kann es für einen kurzen Zeitraum zu einer logischen Trennung kommen, aber nur, wenn acks=1 и min.insync.replicas auch 1. Die logische Trennung endet automatisch, entweder nachdem das Netzwerk wiederhergestellt ist, wenn der ursprüngliche Leiter erkennt, dass er nicht mehr der Leiter ist, oder wenn alle Clients erkennen, dass der Leiter gewechselt hat und beginnen, an den neuen Leiter zu schreiben – je nachdem, was zuerst eintritt. In jedem Fall gehen einige Nachrichten verloren, jedoch nur mit acks=1.

Es gibt eine weitere Variante dieses Szenarios, bei der kurz vor der Netzwerkspaltung die Follower zurückfielen und der Anführer den ISR auf sich selbst komprimierte. Aufgrund des Verbindungsverlusts wird es dann isoliert. Ein neuer Anführer wird gewählt, aber der ursprüngliche Anführer nimmt weiterhin Einträge an, auch wenn dies nicht der Fall ist acks=alle, weil es außer ihm niemanden in der ISR gibt. Diese Datensätze gehen verloren, sobald das Netzwerk wiederhergestellt ist. Die einzige Möglichkeit, diese Option zu vermeiden, ist min.insync.replicas = 2.

Szenario 7: Der Kafka-Controller-Knoten kann keinen anderen Kafka-Knoten sehen

Sobald die Verbindung zu einem Kafka-Knoten verloren geht, kann der Controller im Allgemeinen keine Leader-Änderungsinformationen an ihn übermitteln. Dies führt im schlimmsten Fall zu einer kurzfristigen logischen Trennung, wie in Szenario 6. In den meisten Fällen wird der Makler einfach kein Kandidat für die Führung, wenn diese scheitert.

Szenario 8: Der Kafka-Controller erkennt Zookeeper nicht

Zookeeper erhält keinen Ping vom ausgefallenen Controller und wählt einen neuen Kafka-Knoten als Controller aus. Der ursprüngliche Controller kann sich weiterhin als solcher präsentieren, erhält jedoch keine Benachrichtigungen von Zookeeper und muss daher keine Aufgaben ausführen. Sobald das Netzwerk wiederhergestellt ist, wird ihm klar, dass er kein Controller mehr ist, sondern zu einem regulären Kafka-Knoten geworden ist.

Schlussfolgerungen aus den Szenarien

Wir sehen, dass der Verlust der Follower-Konnektivität nicht zu einem Nachrichtenverlust führt, sondern lediglich vorübergehend die Redundanz verringert, bis das Netzwerk wiederhergestellt ist. Dies kann natürlich zu Datenverlust führen, wenn ein oder mehrere Knoten verloren gehen.

Wenn der Anführer aufgrund eines Verbindungsverlusts vom Zookeeper getrennt wird, kann dies dazu führen, dass Nachrichten verloren gehen acks=1. Mangelnde Kommunikation mit Zookeeper führt zu einer kurzen logischen Spaltung zwischen den beiden Anführern. Dieses Problem wird durch den Parameter gelöst acks=alle.

Parameter min.insync.replicas Die Aufteilung in zwei oder mehr Replikate bietet zusätzliche Sicherheit, dass solche kurzfristigen Szenarien nicht zu Nachrichtenverlusten wie in Szenario 6 führen.

Zusammenfassung verlorener Nachrichten

Lassen Sie uns alle Möglichkeiten auflisten, wie Sie in Kafka Daten verlieren können:

  • Jeder Leader-Fehler, wenn Nachrichten mit bestätigt wurden acks=1
  • Jeder unsaubere Übergang der Führung, also zu einem Gefolgsmann außerhalb der ISR, auch mit acks=alle
  • Isolieren des Anführers von Zookeeper, wenn Nachrichten mit bestätigt wurden acks=1
  • Völlige Isolation des Anführers, der die ISR-Gruppe bereits auf sich selbst geschrumpft hat. Alle Nachrichten gehen sogar verloren acks=alle. Dies gilt nur, wenn min.insync.replicas=1.
  • Gleichzeitige Ausfälle aller Partitionsknoten. Da Nachrichten aus dem Speicher bestätigt werden, sind einige möglicherweise noch nicht auf die Festplatte geschrieben. Nach dem Neustart der Server fehlen möglicherweise einige Meldungen.

Unreine Führungswechsel können vermieden werden, indem man sie entweder verbietet oder für mindestens zwei Entlassungen sorgt. Die haltbarste Konfiguration ist eine Kombination acks=alle и min.insync.replicas mehr als 1.

Direkter Vergleich der Zuverlässigkeit von RabbitMQ und Kafka

Um Zuverlässigkeit und hohe Verfügbarkeit zu gewährleisten, implementieren beide Plattformen ein primäres und sekundäres Replikationssystem. Allerdings hat RabbitMQ eine Achillesferse. Bei der Wiederherstellung der Verbindung nach einem Fehler verwerfen Knoten ihre Daten und die Synchronisierung wird blockiert. Dieser Doppelschlag stellt die Langlebigkeit großer Warteschlangen in RabbitMQ in Frage. Sie müssen entweder eine reduzierte Redundanz oder lange Sperrzeiten in Kauf nehmen. Die Reduzierung der Redundanz erhöht das Risiko eines massiven Datenverlusts. Wenn die Warteschlangen jedoch klein sind, können kurze Zeiträume der Nichtverfügbarkeit (einige Sekunden) aus Redundanzgründen durch wiederholte Verbindungsversuche überwunden werden.

Kafka hat dieses Problem nicht. Es verwirft Daten nur ab dem Punkt der Divergenz zwischen dem Anführer und dem Anhänger. Alle freigegebenen Daten werden gespeichert. Darüber hinaus blockiert die Replikation das System nicht. Der Anführer nimmt weiterhin Beiträge an, während der neue Follower aufholt, sodass der Beitritt oder erneute Beitritt zum Cluster für Entwickler zu einer trivialen Aufgabe wird. Natürlich gibt es immer noch Probleme wie die Netzwerkbandbreite während der Replikation. Wenn Sie mehrere Follower gleichzeitig hinzufügen, kann es zu einer Bandbreitenbeschränkung kommen.

RabbitMQ ist Kafka hinsichtlich der Zuverlässigkeit überlegen, wenn mehrere Server in einem Cluster gleichzeitig ausfallen. Wie bereits erwähnt, sendet RabbitMQ erst dann eine Bestätigung an den Herausgeber, wenn die Nachricht vom Master und allen Spiegeln auf die Festplatte geschrieben wurde. Dies führt jedoch aus zwei Gründen zu zusätzlicher Latenz:

  • fsync alle paar hundert Millisekunden
  • Der Ausfall des Spiegels kann erst bemerkt werden, wenn die Lebensdauer der Pakete, die die Verfügbarkeit jedes Knotens überprüfen (Net-Tick), abgelaufen ist. Wenn der Spiegel langsamer wird oder herunterfällt, kommt es zu einer Verzögerung.

Kafkas Wette besteht darin, dass, wenn eine Nachricht über mehrere Knoten hinweg gespeichert wird, Nachrichten bestätigt werden können, sobald sie im Speicher ankommen. Aus diesem Grund besteht die Gefahr, dass Nachrichten jeglicher Art (sogar) verloren gehen acks=alle, min.insync.replicas=2) bei gleichzeitigem Ausfall.

Insgesamt weist Kafka eine bessere Softwareleistung auf und ist von Grund auf für Cluster konzipiert. Die Anzahl der Follower kann bei Bedarf aus Zuverlässigkeitsgründen auf 11 erhöht werden. Replikationsfaktor 5 und Mindestanzahl von Replikaten in der Synchronisierung min.insync.replicas=3 Dadurch wird der Verlust einer Nachricht zu einem sehr seltenen Ereignis. Wenn Ihre Infrastruktur dieses Replikationsverhältnis und diese Redundanzstufe unterstützen kann, können Sie diese Option wählen.

RabbitMQ-Clustering eignet sich gut für kleine Warteschlangen. Aber auch kleine Warteschlangen können bei starkem Verkehr schnell wachsen. Sobald die Warteschlangen groß werden, müssen Sie schwierige Entscheidungen zwischen Verfügbarkeit und Zuverlässigkeit treffen. RabbitMQ-Clustering eignet sich am besten für untypische Situationen, in denen die Vorteile der Flexibilität von RabbitMQ die Nachteile des Clusterings überwiegen.

Ein Gegenmittel gegen die Anfälligkeit von RabbitMQ gegenüber großen Warteschlangen besteht darin, sie in viele kleinere Warteschlangen aufzuteilen. Wenn Sie nicht die vollständige Reihenfolge der gesamten Warteschlange benötigen, sondern nur die relevanten Nachrichten (z. B. Nachrichten von einem bestimmten Kunden) oder überhaupt nichts bestellen möchten, ist diese Option akzeptabel: Sehen Sie sich mein Projekt an Rebalancer um die Warteschlange zu teilen (das Projekt befindet sich noch in einem frühen Stadium).

Vergessen Sie schließlich nicht die zahlreichen Fehler in den Clustering- und Replikationsmechanismen von RabbitMQ und Kafka. Mit der Zeit sind die Systeme ausgereifter und stabiler geworden, aber keine Nachricht wird jemals zu 100 % vor Verlust sicher sein! Darüber hinaus kommt es in Rechenzentren zu Großunfällen!

Wenn ich etwas übersehen habe, einen Fehler gemacht habe oder Sie mit einem der Punkte nicht einverstanden sind, können Sie gerne einen Kommentar schreiben oder mich kontaktieren.

Ich werde oft gefragt: „Was soll ich wählen, Kafka oder RabbitMQ?“, „Welche Plattform ist besser?“. Die Wahrheit ist, dass es wirklich von Ihrer Situation, Ihren aktuellen Erfahrungen usw. abhängt. Ich zögere, meine Meinung zu äußern, da es zu stark vereinfacht wäre, eine Plattform für alle Anwendungsfälle und möglichen Einschränkungen zu empfehlen. Ich habe diese Artikelserie geschrieben, damit Sie sich eine eigene Meinung bilden können.

Ich möchte sagen, dass beide Systeme in diesem Bereich führend sind. Vielleicht bin ich etwas voreingenommen, weil ich aufgrund meiner Erfahrung mit Projekten dazu tendiere, Dinge wie garantierte Nachrichtenreihenfolge und Zuverlässigkeit zu schätzen.

Ich sehe andere Technologien, denen diese Zuverlässigkeit und garantierte Ordnung fehlt, dann schaue ich mir RabbitMQ und Kafka an und erkenne den unglaublichen Wert dieser beiden Systeme.

Source: habr.com

Kommentar hinzufügen