Heim >Backend-Entwicklung >PHP-Tutorial >Detaillierte Erläuterung der verteilten Sperrimplementierung in Redis

Detaillierte Erläuterung der verteilten Sperrimplementierung in Redis

小云云
小云云Original
2017-12-14 14:42:412485Durchsuche

Die zuvor verwendeten geplanten Aufgaben wurden nur auf einer einzelnen Maschine bereitgestellt. Um das Einzelpunktproblem zu lösen und sicherzustellen, dass eine Aufgabe nur von einer Maschine ausgeführt wird, müssen wir das Sperrproblem berücksichtigen und daher Zeit aufwenden habe dieses Problem untersucht. Wie implementiert man eine verteilte Sperre? In diesem Artikel werden hauptsächlich Beispiele für die Implementierung verteilter Sperren in Redis vorgestellt. Ich werde sie nun mit Ihnen teilen und Ihnen hoffentlich helfen.

Das Wesentliche einer Sperre ist der gegenseitige Ausschluss, der sicherstellt, dass ein Client jederzeit dieselbe Sperre halten kann. Wenn Sie Redis zur Implementierung einer verteilten Sperre in Betracht ziehen, besteht die einfachste Lösung darin, einen Schlüsselwert zu erstellen Wenn die Sperre aufgehoben wird, wird der Schlüsselwert gelöscht. Für eine zuverlässige und vollständige verteilte Sperre müssen jedoch viele Details berücksichtigt werden. Schauen wir uns an, wie man eine korrekte verteilte Sperre schreibt.

Eigenständige verteilte Sperre SETNX

Also implementieren wir eine einfache Sperre direkt basierend auf dem Befehl setNX (SET if Not eXists) von redis. Gehen Sie direkt zum Pseudocode

Sperrenerfassung:

SET resource_name my_random_value NX PX 30000

Sperrenfreigabe:

 if redis.call("get",KEYS[1]) == ARGV[1] then
  return redis.call("del",KEYS[1])
 else
  return 0
 end

Ein paar Details müssen beachtet werden:

Zuerst müssen wir das Timeout beim Erwerb der Sperre festlegen. Die Zeitüberschreitung soll verhindern, dass der Client abstürzt oder die Sperre aufrechterhalten wird, nachdem ein Netzwerkproblem auftritt. Das ganze System ist festgefahren.

Verwenden Sie den Befehl setNX, um sicherzustellen, dass die Abfrage- und Schreibschritte atomar sind

Wenn die Sperre aufgehoben wird, beurteilen wir, dass KEYS[1]) == ARGV[1], hier KEYS [ 1] ist der von redis übernommene Wert und ARGV[1] ist der oben generierte my_random_value. Der Grund für das obige Urteil besteht darin, sicherzustellen, dass die Sperre durch den gesperrten Inhaber freigegeben wird. Wir gehen davon aus, dass dieser Schritt der Überprüfung nicht durchgeführt wird:

  1. Client A erhält die Sperre und der nachfolgende Thread bleibt hängen. Die Zeit ist größer als die Ablaufzeit der Sperre.

  2. Nach Ablauf der Sperre erhält Client B die Sperre.

  3. Nachdem sich Client A erholt hat und zugehörige Ereignisse verarbeitet hat, initiiert er einen Del-Befehl für Redis. Die Sperre wird aufgehoben

  4. Client C erwirbt die Sperre. Zu diesem Zeitpunkt halten zwei Clients in einem System gleichzeitig Sperren.

Der Schlüssel zu diesem Problem liegt darin, dass die von Client B gehaltene Sperre von Client A freigegeben wurde.

Die Sperre muss mithilfe eines Lua-Skripts aufgehoben werden, um die Atomizität des Vorgangs sicherzustellen. Die Freigabe der Sperre umfasst drei Schritte: Get, Judgement und Del. Wenn die Atomizität der drei Schritte nicht garantiert werden kann, treten bei verteilten Sperren Parallelitätsprobleme auf.

Nachdem Sie die oben genannten Details beachtet haben, wird eine verteilte Sperre eines einzelnen Redis-Knotens erreicht.

In dieser verteilten Sperre gibt es immer noch einen einzigen Redis-Punkt. Vielleicht werden Sie sagen, dass Redis eine Master-Slave-Architektur hat. Wenn ein Fehler auftritt, wechseln Sie einfach zum Slave, aber die Redis-Replikation erfolgt asynchron.

  1. Wenn Client A die Sperre für den Master erhält.

  2. Bevor der Master die Daten mit dem Slave synchronisiert, geht der Master aus.

  3. Client B erhält die Sperre erneut vom Slave.

Auf diese Weise halten aufgrund der Ausfallzeit des Masters mehrere Personen gleichzeitig die Sperre. Wenn Ihr System es zulässt, dass mehrere Personen das Schloss für kurze Zeit halten. Diese einfache Lösung wird das Problem lösen.

Aber wenn dieses Problem gelöst ist. Redis stellt offiziell eine Redlock-Lösung bereit.

Implementierung von RedLock

Um das Problem des Redis-Einzelpunkts zu lösen. Der Autor von Redis schlug die Lösung von RedLock vor. Der Plan ist sehr clever und prägnant.
Die Kernidee von RedLock besteht darin, aus Redundanzgründen mehrere Redis-Master gleichzeitig zu verwenden. Diese Knoten sind völlig unabhängig und es besteht keine Notwendigkeit, Daten zwischen diesen Knoten zu synchronisieren.

Angenommen, wir haben N Redis-Knoten, N sollte eine ungerade Zahl größer als 2 sein. RedLock-Implementierungsschritte:

  1. Erhalten Sie die aktuelle Zeit

  2. Verwenden Sie die oben genannte Methode, um die Redis-Sperren von N Knoten nacheinander abzurufen.

  3. Wenn die Anzahl der erworbenen Sperren größer als (N/2+1) ist und die Erfassungszeit kürzer als die Sperrgültigkeitszeit (Sperrengültigkeitszeit) ist, wird davon ausgegangen, dass a Eine gültige Sperre wurde erworben. Die automatische Freigabezeit des Schlosses ist die anfängliche Freigabezeit des Schlosses abzüglich der Zeit, die zuvor für den Erwerb der Sperre aufgewendet wurde.

  4. Wenn die Anzahl der erworbenen Sperren weniger als (N/2+1) beträgt oder nicht genügend innerhalb der Sperrgültigkeitszeit (Sperrengültigkeitszeit) erworben werden, wird davon ausgegangen, dass die Die Sperrenerfassung ist fehlgeschlagen. Zu diesem Zeitpunkt müssen Sperrfreigabenachrichten an alle Knoten gesendet werden.

Die Umsetzung der Freigabe der Sperre ist sehr einfach. Initiieren Sie einen Freigabevorgang auf allen Redis-Knoten, unabhängig davon, ob die Sperre zuvor erfolgreich erworben wurde.

Gleichzeitig müssen Sie auf mehrere Details achten:

Das Intervall zwischen den Wiederholungsversuchen zur Erlangung der Sperre sollte ein zufälliger Bereich sein und keine feste Zeit. Dies kann verhindern, dass mehrere Clients gleichzeitig Sperrenerfassungsvorgänge an den Redis-Cluster senden, und gleichzeitigen Wettbewerb vermeiden. Die Situation, die gleiche Anzahl von Schlössern gleichzeitig zu erwerben. (Obwohl die Wahrscheinlichkeit sehr gering ist)

Wenn ein Masterknoten ausfällt, sollte das Wiederherstellungszeitintervall größer sein als die Sperrgültigkeitszeit.

  1. Angenommen, es gibt drei Redis-Knoten A, B und C.

  2. Kunde foo erwirbt zwei Schlösser A und B.

  3. Zu diesem Zeitpunkt ist B ausgefallen und alle Daten im Speicher gehen verloren.

  4. Knoten B antwortet.

  5. Zu diesem Zeitpunkt erhält die Client-Leiste die Sperre erneut und erhält zwei Knoten, B und C.

  6. Zu diesem Zeitpunkt haben zwei weitere Kunden das Schloss erworben.

Wenn also die Wiederherstellungszeit länger ist als die effektive Zeit der Sperre, kann die oben genannte Situation vermieden werden. Wenn die Leistungsanforderungen nicht hoch sind, können Sie gleichzeitig sogar die Persistenzoption von Redis aktivieren.

Zusammenfassung

Nachdem ich die Implementierung der Redis-Verteilung verstanden habe, habe ich tatsächlich das Gefühl, dass die Prinzipien der meisten verteilten Systeme sehr einfach sind, aber um die Zuverlässigkeit des zu gewährleisten Verteiltes System Es muss auf viele Details geachtet werden, trivial und anormal.

Die vom RedLock-Algorithmus implementierte verteilte Sperre ist einfach und effizient, und die Idee ist ziemlich clever.

Aber ist RedLock unbedingt sicher? Ich werde auch einen Artikel zu diesem Thema schreiben. Bitte bleiben Sie dran.

Verwandte Empfehlungen:

Detaillierte Erläuterung des Prinzips der Redisson-Methode zur Implementierung verteilter Sperren

Detaillierte Erläuterung der verteilten PHP-Redis-Sperren und Codebeispiele für Aufgabenwarteschlangen

Mehrere Implementierungsmethoden für verteilte Sperren

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der verteilten Sperrimplementierung in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn