LMAX Replicator Design - Wie unterstützt man Hochverfügbarkeit?

8

LMAX-Disruptor wird im Allgemeinen unter Verwendung des folgenden Ansatzes implementiert:

Wie in diesem Beispiel ist Replicator verantwortlich für die Replikation der Eingabeereignisse \ Befehle an die Slave-Knoten. Die Replikation über eine Gruppe von Knoten erfordert die Anwendung von Konsensalgorithmen, falls das System bei Netzwerkausfällen, Masterfehlern und Slaveausfällen verfügbar sein soll.

Ich dachte daran, den RAFT-Konsensus-Algorithmus auf dieses Problem anzuwenden. Eine Beobachtung ist folgende: "RAFT erfordert, dass die Eingabe-Ereignisbefehle während der Replikation auf dem Datenträger (dauerhafter Speicher) gespeichert werden" (Verweis auf diesen Link)

Diese Beobachtung bedeutet im Wesentlichen, dass wir keine In-Memory-Replikation durchführen können. Daher scheint es, dass wir die Funktionalität von Replikator und Journaler kombinieren müssen, um den RAFT-Algorithmus erfolgreich auf LMAX anwenden zu können.

Dafür gibt es zwei Möglichkeiten:

Option 1: Verwenden des replizierten Protokolls als Eingangsereigniswarteschlange

  • Der Empfänger würde aus dem Netzwerk lesen und das Ereignis anstelle des Ringpuffers auf das replizierte Protokoll schieben
  • Ein separater "Leser" kann aus dem Protokoll lesen und die Ereignisse im Ringpuffer veröffentlichen.
  • Das Protokoll kann über Knoten mit RAFT repliziert werden. Wir benötigen den Replikator und den Journaler nicht, da die Funktionalität bereits von RAFTs repliziertem Protokoll erfüllt wird.

Ich denke, ein Nachteil dieser Option hat damit zu tun, dass wir einen zusätzlichen Datenkopierschritt (Empfänger zu Ereigniswarteschlange anstelle des Ringpuffers) machen.

Option 2: Verwenden Sie den Replikator, um Eingabeereignisse \ Befehle in die Eingabeprotokolldatei des Slaves zu schieben

Ich habe mich gefragt, ob es eine andere Lösung für das Design von Replicator gibt? Welche unterschiedlichen Gestaltungsmöglichkeiten haben die Menschen für Replikatoren? Insbesondere jedes Design, das In-Memory-Replikation unterstützen kann?

    
Ngm 08.05.2014, 07:46
quelle

1 Antwort

6

Ihre Intuition ist richtig, wenn Sie die Replikation und das Journaling in die Floßkomponente falten. Aber das Raft-Protokoll schreibt genau vor, wann Dinge auf der Festplatte gespeichert werden müssen.

Hier sind zwei verschiedene Möglichkeiten, es zu betrachten.

Ich gehe davon aus, dass es vor der Replikation keine aufwendige Berechnung, wie etwa eine Transaktionsverarbeitung, gibt, weil Sie keine in Ihren Diagrammen haben.

Ich persönlich würde das erste machen, weil es Bedenken in verschiedene Prozesse trennt. Wenn ich Raft für mich selbst implementieren würde, würde ich die erste Hälfte des zweiten Szenarios nehmen und es in einen eigenen Prozess bringen.

Externe Floßreplikation

In dem Raft durch einen externen Prozess implementiert wird.

Die Replikationskomponente lagert den Geschäftsprozess der Replikation an einen externen Floßprozess aus. Nach einiger Zeit antwortet Floß auf die Replikationskomponente, die tatsächlich repliziert wird. Die Replikationskomponente aktualisiert die Elemente im Ringpuffer und verschiebt den veröffentlichten Cursor nach vorne. Die Geschäftslogik sieht den veröffentlichten Cursor (über waitFor ) und verwendet die frisch replizierten Daten.

In diesem Szenario hat die Replikationskomponente wahrscheinlich viele Inflight-Ereignisse, so dass der Lese-Cursor dem Cursor, der in der Geschäftslogik veröffentlicht wird, weit voraus ist.

In diesem Szenario ist keine journalling -Komponente erforderlich, da das externe Floßsystem das Journaling für Sie übernimmt.

Beachten Sie, dass die Replikation möglicherweise die langsamste Komponente des Systems ist!

Integrierte Floßreplikation

In diesem Floß wird im selben Prozess wie die "Real Business Logic" implementiert.

In Bezug auf Floss ist Replikation die Geschäftslogik. Tatsächlich haben Sie mehrere Ebenen der Geschäftslogik oder äquivalent mehrere Stufen der Geschäftslogik.

Ich werde zwei Input-Disruptoren und zwei Output-Disruptoren verwenden, um die separate Geschäftslogik hervorzuheben. Sie können den Inhalt Ihres Herzens kombinieren, teilen oder neu anordnen. Oder der Inhalt deines Profilers.

Die erste Stufe ist, wie ich bereits erwähnte, die Floßreplikation. Client-Ereignisse werden in den Replikationseingabe-Disruptor verschoben. Die Floßlogik nimmt sie auf, vielleicht in Stapeln, und sendet sie an die Folger auf dem Replikationsausgangsstörer. Alle Raft-Nachrichten werden auch in den Replikationseingabe-Disruptor übertragen. Die Raft-Logik nimmt diese ebenfalls auf und sendet die entsprechenden Antworten an die entsprechenden Follower / Master des Replication Output Disruptors.

Eine Journalkomponente hängt vom Eingangsringpuffer ab; es muss nur bestimmte Arten von Nachrichten behandeln, wie von Floß vorgeschrieben. Dies wird wahrscheinlich der langsamste Teil des Systems sein.

Wenn die Daten als repliziert betrachtet werden, werden sie über den Input Disruptor "Real Business Logic" in die zweite Stufe verschoben. Dort wird es verarbeitet, an den Client Outbound Disruptor gesendet und dann an einen Ihrer Millionen glücklich zahlender Kunden gesendet.

    
Michael Deardeuff 14.06.2014, 04:52
quelle