Wie Server miteinander verhandeln: Raft Distributed Consensus-Algorithmus

Wenn Cluster Hunderte und manchmal Tausende von Maschinen erreichen, stellt sich die Frage nach der Konsistenz der ServerzustĂ€nde relativ zueinander. Der Raft Distributed Consensus-Algorithmus bietet die strengste Konsistenzgarantie. In diesem Artikel werden wir Raft aus der Sicht eines Ingenieurs betrachten und versuchen, die Fragen „Wie?“ Zu beantworten. und "warum?" es funktioniert.




Artikelautor : Dmitry Pavlushin (Entwickler Dodo Pizza Engineering).

Raft ist ein verteilter Konsensalgorithmus , der benötigt wird, damit mehrere Teilnehmer gemeinsam entscheiden können, ob und was passiert ist oder nicht.

Die vom Raft-Cluster bereitgestellten Daten sind ein Protokoll, das aus DatensĂ€tzen besteht. Wenn ein Benutzer die in einem Cluster gespeicherten Daten Ă€ndern möchte, versucht er, dem Protokoll mit dem folgenden Befehl einen neuen Datensatz hinzuzufĂŒgen:


Diese Befehle werden von verteilten Zustandsautomaten ausgefĂŒhrt. Der Einfachheit und Klarheit halber gehen wir im Rahmen dieses Artikels davon aus, dass diese DatensĂ€tze einfach an einen Kunden weitergegeben werden, der basierend auf den aufgetretenen Ereignissen den aktuellen Status des Systems wiederherstellt (siehe Ereignisbeschaffung) .

Um einen Konsens in Raft zu gewĂ€hrleisten, wird zunĂ€chst ein Leiter ausgewĂ€hlt, der fĂŒr die Verwaltung des verteilten Protokolls verantwortlich ist. Der Leiter akzeptiert Anforderungen von Clients und repliziert sie auf andere Server im Cluster. Wenn der AnfĂŒhrer ausfĂ€llt, wird ein neuer AnfĂŒhrer im Cluster ausgewĂ€hlt. Dies ist, wenn fĂŒr eine Weile in drei SĂ€tzen. Details folgen.

Grundbegriffe


  1. Serverstatus Im Raft-Cluster befindet sich jeder Server zu einem bestimmten Zeitpunkt in einem von drei ZustÀnden:
    • Leader (Leader) - verarbeitet alle Client-Anfragen, ist die Quelle der Wahrheit aller Daten im Protokoll und unterstĂŒtzt das Follower-Protokoll.
    • Follower (Follower) ist ein passiver Server, der nur neue ProtokolleintrĂ€ge des Leiters „abhört“ und alle eingehenden Anforderungen von Clients an den Leiter umleitet. TatsĂ€chlich handelt es sich um eine Hot-Standby-Nachbildung des AnfĂŒhrers.
    • Kandidat (Kandidat) ist ein spezieller Status des Servers, der nur wĂ€hrend der Auswahl eines neuen Leiters möglich ist.

    WĂ€hrend des normalen Betriebs in einem Cluster ist nur ein Server der AnfĂŒhrer, der Rest sind seine AnhĂ€nger.

    Über Asynchronismus
    Es ist erwĂ€hnenswert, dass die Bedingung ein relatives Konzept ist. Aufgrund der Tatsache, dass die Server asynchron kommunizieren, können verschiedene Server die ÜbergĂ€nge anderer Server zu unterschiedlichen Zeiten von einem Status in einen anderen beobachten.
  2. Das Floß unterteilt die Zeit in Segmente beliebiger LĂ€nge, die als Fristen bezeichnet werden . Jeder Begriff hat eine monoton ansteigende Anzahl. Die Amtszeit beginnt mit der Wahl eines Leiters, wenn ein oder mehrere Server Kandidaten werden. Wenn der Kandidat die Mehrheit der Stimmen erhĂ€lt, wird er bis zum Ende dieses Zeitraums fĂŒhrend. Wenn die Stimmen geteilt sind und keiner der Kandidaten die Mehrheit der Stimmen erhalten kann, wird eine ZeitĂŒberschreitung ausgelöst und dieser Zeitraum endet. Danach beginnt eine neue Amtszeit mit neuen Kandidaten und Wahlen. Diese Situation wird als getrennte Abstimmung bezeichnet. Ein Beispiel wird durch den dritten Begriff in der folgenden Abbildung veranschaulicht:


    Die Termnummer dient als logischer Zeitstempel im Raft-Cluster. Es hilft Servern zu bestimmen, welche Informationen momentan relevanter sind.

    Regeln und Bedingungen fĂŒr die Serverinteraktion
    • Jeder Server verfolgt die Nummer seiner aktuellen Laufzeit.
    • Der Server enthĂ€lt seine Ablaufnummer in jeder gesendeten Nachricht.
    • Wenn der Server eine Nachricht mit einer geringeren Laufzeitnummer als seiner eigenen empfĂ€ngt, ignoriert er diese Nachricht.
    • Wenn der Server eine Nachricht mit einer lĂ€ngeren Frist als seiner eigenen empfĂ€ngt, aktualisiert er seine Frist so, dass sie mit der empfangenen ĂŒbereinstimmt.
    • Wenn ein Kandidat oder Leiter eine Nachricht mit einer lĂ€ngeren Frist als seiner eigenen erhĂ€lt, versteht er, dass andere Server bereits eine neue Frist eingeleitet haben und seine Frist nicht mehr relevant ist. Daher wechselt es zusĂ€tzlich zur Aktualisierung seiner Nummer vom aktuellen Status in den Status "Follower".

  3. Serverkommunikation. Die Server in Raft interagieren, indem sie Anforderungen und Antworten austauschen. Der grundlegende Algorithmus verwendet nur zwei Arten von Aufrufen:

    • RequestVote wird von Kandidaten wĂ€hrend der Wahlen verwendet. Die Anfrage enthĂ€lt die Termnummer des Kandidaten und Metadaten zum Protokoll des Kandidaten, die nachstehend ausfĂŒhrlicher erlĂ€utert werden. Die Antwort enthĂ€lt die Deadline-Nummer des antwortenden Servers und den Wert "true", wenn der Server fĂŒr den Kandidaten stimmt. False, wenn der Server gegen den Kandidaten stimmt.
    • AppendEntries wird vom Leader fĂŒr die Protokollreplikation sowie fĂŒr den Heartbeat-Mechanismus verwendet. Die Anforderung enthĂ€lt die Termnummer des Leiters, eine Sammlung von EintrĂ€gen, die dem Protokoll hinzugefĂŒgt werden mĂŒssen (oder eine leere Sammlung im Falle eines Herzschlags), einige Metadaten zum Protokoll des Leiters, die im Folgenden ebenfalls ausfĂŒhrlicher erlĂ€utert werden. Die Antwort enthĂ€lt die Nummer des Follower-Terms und den Wert "true", wenn der Follower erfolgreich EintrĂ€ge zu seinem Protokoll hinzugefĂŒgt hat. "False", wenn das HinzufĂŒgen von ProtokolleintrĂ€gen fehlgeschlagen ist.

Arbeitsalgorithmus


1. WĂ€hlen Sie einen FĂŒhrer


Um festzustellen, wann es Zeit ist, eine Neuwahl zu beginnen, setzt Raft auf Herzschlag. Der Follower bleibt der Follower, bis er Nachrichten vom aktuellen AnfĂŒhrer oder Kandidaten erhĂ€lt. Der Leader sendet regelmĂ€ĂŸig Heartbeat an alle anderen Server.

Wenn der Follower einige Zeit keine Nachrichten erhĂ€lt, geht er ganz natĂŒrlich davon aus, dass der AnfĂŒhrer tot ist, was bedeutet, dass es Zeit ist, die Initiative in seine HĂ€nde zu nehmen. Zu diesem Zeitpunkt leitet der frĂŒhere AnhĂ€nger die Wahl ein.

Um die Wahl einzuleiten, erhöht der Follower seine Laufzeitnummer, wechselt in den Status "Kandidat", stimmt fĂŒr sich selbst und sendet dann die Anforderung "RequestVote" an alle anderen Server. Danach wartet der Kandidat auf eines von drei Ereignissen:

  1. Der Kandidat erhĂ€lt die Mehrheit der Stimmen (einschließlich seiner eigenen) und gewinnt die Wahl. Jeder Server stimmt nur einmal in jeder Amtszeit ab, damit der erste Kandidat erreicht wird (mit einigen Ausnahmen, die unten erlĂ€utert werden). Daher kann nur ein Kandidat die Mehrheit der Stimmen in einer bestimmten Amtszeit erhalten. Der Gewinner-Server wird zum Leader, sendet Heartbeat und bedient Client-Anforderungen an den Cluster.
  2. Der Kandidat erhĂ€lt eine Nachricht vom aktuellen Leiter der aktuellen Amtszeit oder von einem Server mit einer Ă€lteren Amtszeit . In diesem Fall versteht der Kandidat, dass die Wahlen, an denen er teilnimmt, nicht mehr relevant sind. Er hat keine andere Wahl, als einen neuen FĂŒhrer / eine neue Amtszeit zu erkennen und in einen Zustand des Nachfolgers zu gelangen.
  3. Ein Kandidat erhĂ€lt fĂŒr eine bestimmte Zeit keine Mehrheit der Stimmen. Dies kann passieren, wenn mehrere AnhĂ€nger Kandidaten werden und die Stimmen unter ihnen aufgeteilt werden, so dass nicht einer die Mehrheit erhĂ€lt. In diesem Fall endet die Amtszeit ohne FĂŒhrer, und der Kandidat beginnt sofort mit Neuwahlen fĂŒr die nĂ€chste Amtszeit.

2. Wir replizieren Protokolle


Wenn ein Leiter ausgewĂ€hlt wird, ist er fĂŒr die Verwaltung des verteilten Protokolls verantwortlich. Der Leiter akzeptiert Anfragen von Kunden, die einige Teams enthalten. Der AnfĂŒhrer fĂŒgt in sein Protokoll einen neuen Datensatz ein, der den Befehl enthĂ€lt, und sendet dann "AppendEntries" an alle Follower, um den Datensatz mit dem neuen Datensatz zu replizieren.

Wenn der Datensatz auf den meisten Servern erfolgreich repliziert wurde, betrachtet der Leiter den Datensatz als geschlossen und antwortet dem Client. Der AnfĂŒhrer verfolgt, welcher Datensatz der letzte ist. Es sendet die Nummer dieses Datensatzes an AppendEntries (einschließlich Heartbeat), damit Follower den Datensatz fĂŒr sich selbst festschreiben können.

Falls der AnfĂŒhrer einige Follower nicht erreichen kann, wird er die AppendEntries bis ins Unendliche zurĂŒckverfolgen. Das folgende Bild zeigt, wie die Protokolle im Raft-Cluster organisiert sind:



Jedes Feld ist ein Eintrag im Protokoll. Jeder Datensatz speichert einen Befehl, z. B. x ← 3 weist der Taste x den Wert 3 zu. Der Datensatz speichert auch die Nummer des Begriffs, in dem er generiert wurde. Auf dem Bild wird dies durch eine Zahl am oberen Rand des Quadrats angezeigt. Die Farbanzeige der Quadrate bedeutet auch die Termnummer. Jeder Datensatz hat eine Seriennummer (Protokollindex).

3. Wir garantieren die ZuverlÀssigkeit des Algorithmus


Bisher ist nach unseren Untersuchungen nicht klar, wie Raft zumindest einige Garantien geben kann. Der Algorithmus bietet jedoch eine Reihe von Eigenschaften, die zusammen die ZuverlĂ€ssigkeit seiner AusfĂŒhrung gewĂ€hrleisten:

  • Wahlsicherheit : Innerhalb einer Amtszeit kann nicht mehr als ein FĂŒhrer ausgewĂ€hlt werden. Diese Eigenschaft ergibt sich aus der Tatsache, dass jeder Server innerhalb jeder Amtszeit nur einmal abstimmt und fĂŒr die Bildung eines Leiters eine Mehrheit der Stimmen erforderlich ist
  • Nur AnfĂŒhrer anhĂ€ngen : Der AnfĂŒhrer ĂŒberschreibt oder löscht niemals, verschiebt keine EintrĂ€ge in seinem Protokoll, fĂŒgt nur neue EintrĂ€ge hinzu. Diese Eigenschaft folgt direkt aus der Beschreibung des Algorithmus. Die einzige Operation, die ein Leiter mit seinem Protokoll ausfĂŒhren kann, besteht darin, am Ende EintrĂ€ge hinzuzufĂŒgen. Und alle.
  • Protokollabgleich: Wenn die Protokolle von zwei Servern einen Eintrag mit demselben Index und derselben Ablaufnummer enthalten, sind beide Protokolle bis einschließlich dieses Datensatzes identisch.

    Beweis mit mathematischer Induktion und Bildern
    Die mathematische Induktion ist ein Beweis dafĂŒr, wann der erste Schritt darin besteht, eine Aussage fĂŒr einen einfachen Fall zu beweisen. Im zweiten Schritt akzeptieren wir die Aussage wahr fĂŒr einen Fall X. Auf dieser Grundlage versuchen wir, die Aussage fĂŒr einen benachbarten Fall X + 1 zu beweisen. Zusammen helfen diese beiden Schritte, die Aussage fĂŒr alle FĂ€lle zu beweisen.

    In unserer Situation sind leere Protokolle ein einfacher Fall. Es gibt keine Aufzeichnungen, daher gibt es nichts, was die Eigenschaft verletzen könnte.

    Nehmen wir nun an, dass die Protokolle einige EintrĂ€ge enthalten, die unserer Eigenschaft entsprechen. Raft verfĂŒgt ĂŒber einen Mechanismus, der verhindert, dass die Eigenschaft beschĂ€digt wird, wenn sich ein Protokoll Ă€ndert. Dieser Mechanismus wird als KonsistenzprĂŒfung bezeichnet . Schauen wir uns die Beispiele sofort an.

    Gutes Beispiel . Es gibt zum Beispiel einen FĂŒhrer der 4. Amtszeit, es gibt einen AnhĂ€nger. Beide haben ĂŒbereinstimmende Protokolle aus drei EintrĂ€gen.



    Eine Anfrage des Kunden kommt an den Leiter, er fĂŒgt seinem Protokoll einen Eintrag hinzu.



    Der AnfĂŒhrer sendet AppendEntries an den Follower. ZusĂ€tzlich zu dem am hĂ€ufigsten hinzugefĂŒgten Datensatz gibt der Leiter in der Anforderung an, dass der Datensatz bei Index 4 hinzugefĂŒgt werden muss, und bei Index 3 davor muss ein Datensatz aus Term 2 vorhanden sein.



    Der Protokolleintrag bei Index 3 im Follower-Protokoll stimmt mit dem in der Anforderung angegebenen ĂŒberein, sodass der Follower den Eintrag zu seinem Protokoll hinzufĂŒgt und dem Leiter mit Erfolg antwortet. Das Ende.



    Auch ein gutes Beispiel, aber mit einem tragischen Anfang. Jetzt unterscheidet sich das Protokoll des Followers vom Protokoll des aktuellen AnfĂŒhrers.



    Wenn der Leiter eine Anforderung zum HinzufĂŒgen eines Eintrags zum Protokoll erhĂ€lt, sendet er dieselben AppendEntries wie im vorherigen Beispiel.



    Diesmal schlĂ€gt der Follower jedoch fehl, da der Follower nicht mit dem vorherigen Datensatz ĂŒbereinstimmt.



    Was macht der AnfĂŒhrer in diesem Fall? Der AnfĂŒhrer rollt einfach ein wenig zurĂŒck und versucht, dem Follower den Datensatz zuzufĂŒhren, den er selbst fĂŒr Index 3 hĂ€lt. Er nimmt auch den vorherigen Datensatz in die Anfrage auf.



    Jetzt antwortet der Follower mit Erfolg und ĂŒberschreibt die EintrĂ€ge in seinem Protokoll ab Index 3.



    Das Protokoll des Followers kann nach Belieben vom Protokoll des AnfĂŒhrers abweichen. Es sind möglicherweise nicht genĂŒgend EintrĂ€ge enthalten, möglicherweise sind zusĂ€tzliche EintrĂ€ge enthalten. In jedem Fall stellt die KonsistenzprĂŒfung sicher, dass die Protokolle der Follower frĂŒher oder spĂ€ter mit dem Protokoll des AnfĂŒhrers ĂŒbereinstimmen.

  • VollstĂ€ndigkeit des Leiters : Wenn der Protokolleintrag zu einem bestimmten Zeitpunkt festgeschrieben wird, enthalten die Protokolle der Leiter aller nachfolgenden Perioden diesen Datensatz. Diese Eigenschaft bietet uns Haltbarkeitsgarantien.

    Beweis und Bilder
    Stellen Sie sich folgende Situation vor: Drei Server in einem Cluster. Server S1 ist der AnfĂŒhrer der aktuellen ersten Amtszeit. Alle Server haben drei ProtokolleintrĂ€ge.



    Leader S1 empfĂ€ngt eine Anfrage vom Client, fĂŒgt seinem Protokoll einen neuen Datensatz hinzu und sendet AppendEntries an andere S2- und S3-Server.



    Die Aufzeichnung erreicht erfolgreich S2, aber das Netzwerk zwischen S1 und S3 blinkt und die Anforderung geht verloren. Da S1 weiß, dass der Datensatz auf zwei der drei Server vorhanden ist, kann es feststellen, dass der Datensatz festgeschrieben ist, und erfolgreich auf den Client reagieren.

    S1 wird auch erneut versuchen, einen Eintrag zu S3 hinzuzufĂŒgen, bis dies erfolgreich ist. Aber was passiert, wenn S1 ausfĂ€llt und herunterfĂ€hrt? Was passiert außerdem, wenn S3 als erster das Warten satt hat und ein Kandidat wird? S2 wird dafĂŒr stimmen, S3 wird der AnfĂŒhrer der zweiten Amtszeit und bei der nĂ€chsten Aufforderung, einen Datensatz hinzuzufĂŒgen, wird S3 unseren aufgezeichneten Datensatz ĂŒberschreiben?



    TatsĂ€chlich kann diese Situation im Raft-Cluster nicht auftreten. Der Haken dabei ist, dass S2 nicht fĂŒr S3 stimmen wĂŒrde. Warum? Weil das S3-Serverprotokoll zum Zeitpunkt der Abstimmung weniger relevant ist als das S2-Serverprotokoll. Dieser Mechanismus wird als WahlbeschrĂ€nkung bezeichnet. Der Server wĂ€hlt nur dann fĂŒr einen anderen Server, wenn das Protokoll des Kandidaten nicht weniger relevant ist als das Protokoll des WĂ€hlers.

    Raft vergleicht die Relevanz von Protokollen auf zwei Arten:

    • Nummer des letzten Aufnahmedatums
    • ProtokolllĂ€nge

    Die Kandidaten nehmen diese beiden Parameter in die RequestVote-Anfrage auf, damit die Follower die Relevanz ihres Protokolls mit dem Protokoll des Kandidaten vergleichen können.

    "Am wichtigsten" ist das Protokoll, in dem der letzte Datensatz Àlter ist.



    Wenn die Nummern des Begriffs der letzten EintrĂ€ge ĂŒbereinstimmen, ist das Hauptprotokoll das lĂ€ngere Protokoll.



    Wenn beide ĂŒbereinstimmen, sind die Protokolle gleichermaßen relevant und, wie aus der vorherigen Eigenschaft hervorgeht, absolut identisch.



    Es stellt sich heraus, dass das Serverprotokoll, in dem sich ein gesicherter Datensatz befindet, immer relevanter ist als das Protokoll, in dem es nicht vorhanden ist. Und ein Server mit einem gesicherten Datensatz stimmt nicht fĂŒr einen Server, der diesen nicht hat. Und da auf den meisten Servern ein Datensatz aufgezeichnet ist, kann ein Kandidat ohne diesen Datensatz nicht die Mehrheit der Stimmen erhalten und fĂŒhrend werden, um diesen Datensatz von anderen Servern zu entfernen.

  • Sicherheit von Zustandsautomaten: Diese Eigenschaft wird im Original in Bezug auf verteilte Zustandsautomaten beschrieben. In unserem Artikel kann diese Eigenschaft wie folgt beschrieben werden: Wenn ein Server einen Datensatz mit einem bestimmten Index festschreibt, schreibt kein anderer Server einen anderen Datensatz fĂŒr diesen Index fest.

    Diese Eigenschaft folgt aus der Vergangenheit. Wenn der Follower einen Datensatz bei Index N festlegt, ist sein Protokoll identisch mit dem Protokoll des AnfĂŒhrers bis einschließlich N. Die Leader-VollstĂ€ndigkeitseigenschaft garantiert, dass alle nachfolgenden Leader auch diesen gesicherten Datensatz bei Index N enthalten. Dies bedeutet, dass Follower, die in nachfolgenden Perioden einen Datensatz bei Index N festschreiben, denselben Wert festschreiben.

Links zu Materialien fĂŒr weitere Studien


Source: https://habr.com/ru/post/de469999/


All Articles