In diesem Artikel geht es um Sperren in Redis und es wird erläutert, warum Redlock (Redis Distributed Lock) wirklich benötigt wird.
Warum sollten wir Schlösser verwenden?
In einem K12-Bildungsunternehmen, für das ich gearbeitet habe, hatten wir ein Geschäftsszenario wie dieses. Die Unternehmensseite muss den Unterricht für Schüler organisieren. Gelegentlich kommt es zu Rückmeldungen, dass die Unterrichtsstunden des Schülers eindeutig ausreichen, die Unterrichtsstunden jedoch nicht ausreichen. Was noch beängstigender ist, ist, dass gelegentlich die Unterrichtsstunden der Schüler negativ abgezogen werden (die Unterrichtsstunden des Unternehmens werden kostenlos genutzt). [Verwandte Empfehlungen: Redis-Video-Tutorial]
Ein weiteres Beispiel ist das folgende:
Die beiden oben genannten Probleme sind beide Probleme, die durch die Parallelität in unserem Unternehmen verursacht werden. Die Kernlösung für dieses Problem besteht darin, dass nur eine Anfrage gleichzeitig zum Lesen und Schreiben dieser sensiblen (wichtigen) Daten zugelassen werden kann. Daher müssen zu diesem Zeitpunkt verteilte Sperren verwendet werden, um die gleichzeitige Ausführung des Programms einzuschränken.
Was sind die Probleme mit setnx?
Schauen wir uns zunächst an, wie man verteilte Sperren mit Redis implementiert, mit denen jeder vertraut sein muss. Zum Beispiel können wir das am Anfang meines Artikels erwähnte Problem mit der Klassenplanung von Schülern so sperren:
Auf diese Weise verwenden wir routinemäßig setnx, um die Sperre zu implementieren.
Nehmen wir nun an, dass es ein solches Szenario gibt. Als ich A aufforderte, die Sperre zu erhalten, blieb das Programm in Schritt 2 beim Planen von Kursen für Schüler hängen und die Sperre wurde nicht aufgehoben. Dann wird die Sperre zu einem Deadlock. Die nächste Anforderung, denselben Schüler zu bedienen, wird nie gesperrt, und der Schüler kann nicht eingeplant werden. Zu diesem Zeitpunkt müssen Sie die Sperre manuell aufheben.
Um das Deadlock-Problem zu lösen, fügen wir der Sperre eine Ablaufzeit hinzu.
Wenn Anforderung A nach dem Hinzufügen der Ablaufzeit die Sperre nicht aktiv aufhebt, wird sie nach Ablauf der Sperre aktiv freigegeben, sodass Anforderung B auch die Geschäftslogik für die Sperrverarbeitung erhalten kann. Wenn jedoch die Ablaufzeit hinzugefügt wird, stürzt das Programm zwischen den Schritten 1 und 2 ab. Dann wird es immer noch ein Deadlock-Problem geben. Die Ursache dieses Problems liegt darin, dass die beiden Anweisungen setnx und expire keine atomaren Anweisungen sind. Es wäre also schön, wenn Setnx und Expire alle oder keine davon ausführen könnten.
Aus diesem Grund entstand vor Redis2.8 eine große Anzahl von Erweiterungspaketen in der Community, um dieses Problem zu lösen. Um dieses Chaos zu kontrollieren, hat der Beamte in Version 2.8 die erweiterten Parameter der Set-Anweisung hinzugefügt, sodass die Setnx- und Expire-Anweisungen zusammen ausgeführt werden können. Daher sollten wir jetzt verteilte Sperren wie diese verwenden
Das sieht perfekt aus. Unsere Erwartung wurde erfüllt: „Es wäre großartig, wenn setnx und Expire entweder alle oder keines davon ausführen könnten.“ Gehen wir davon aus, dass wir nun das folgende Szenario haben:
Eine Anfrage erhält nun die Sperre und das Sperr-Timeout ist auf 5 Sekunden eingestellt. In Schritt 2 wird die Geschäftslogik ausgeführt, aber aus irgendeinem Grund wurde die Geschäftslogik nach 5 Sekunden nicht abgeschlossen. Zu diesem Zeitpunkt wird die Sperre aufgrund einer Zeitüberschreitung automatisch aufgehoben. Zu diesem Zeitpunkt kam auch Anforderung B und nach Erhalt der Sperre wurde mit der Ausführung der Geschäftslogik begonnen. Zu diesem Zeitpunkt wurde die Geschäftslogik der Anforderung von A ausgeführt, der dritte Schritt gestartet und die Sperre aufgehoben. Zu diesem Zeitpunkt wurde die Sperre auf Anfrage von B erhalten, aber auf Anfrage von A freigegeben. Dann kann die C-Anfrage die Sperre erhalten. Zu diesem Zeitpunkt führen Anforderung B und Anforderung C zu Parallelitätsproblemen. Aus diesem Beispiel ist ersichtlich, dass die Einstellung der Ablaufzeit in verteilten Sperren sehr wichtig ist. Wenn die eingestellte Zeit kürzer als die Antwortzeit dieser Schnittstelle ist, treten dennoch Probleme mit der Parallelität auf. Daher können wir uns auf die Überwachung der Schnittstellenantwortzeit beziehen, um die Ablaufzeit der Sperre festzulegen.
Redlock
Unsere oben genannten Lösungen basieren alle auf einer Single-Point-Redis-Implementierung. Die Single-Point-Redis-Implementierung verteilter Sperren kann grundsätzlich 95 % der Geschäftsszenarien erfüllen. Bei den restlichen 5 % handelt es sich um Geschäftsszenarien mit äußerst strengen Anforderungen an die Datenkonsistenz und Nulltoleranz für Sperrverluste. Zu diesem Zeitpunkt müssen Sie Redlock berücksichtigen. Was Single-Point-Redis betrifft, kommt es zu Datenverlust und Sperrverlust, selbst wenn es eine hohe Verfügbarkeit durch Sentinel gewährleistet, wenn der Masterknoten aus bestimmten Gründen Master-Slave wechselt und die Master-Slave-Datensynchronisation nicht rechtzeitig erfolgt .
Gehen Sie davon aus, dass es mehrere Redis-Instanzen gibt, die keine Replikation oder ein System zum Koordinieren von Daten benötigen. Wir gehen davon aus, dass es 5 Redis-Masterknoten gibt Die Schritte werden wie folgt aussehen:
Erhalten Sie die aktuelle Serverzeit in Millisekunden
Versuchen Sie, den gleichen Schlüssel und Zufallswert zu verwenden, um die Sperre zu erhalten. Der Client sollte beim Erwerb der Sperre eine Zeitüberschreitung haben. Beispielsweise beträgt die Ablaufzeit der Sperre 10 Sekunden, dann beträgt die Zeitüberschreitung für den Erwerb einer einzigen Die Knotensperre sollte etwa 5 bis 50 Millisekunden betragen. Der Zweck besteht darin, sicherzustellen, dass der Client keine zusätzliche Zeit damit verbringt, eine Verbindung zum ausgefallenen Computer herzustellen. Wenn die Daten nicht innerhalb des Timeout-Zeitraums abgerufen werden, wird der Knoten aufgegeben und der nächste Redis-Knoten abgerufen.
Erhalten Sie nach Abschluss der Erfassung die aktuelle Zeit abzüglich der in Schritt 1 erhaltenen Zeit, und zwar genau dann, wenn der Client die Sperre von mehr als der Hälfte (hier 3 Knoten) der Redis-Knoten erhält und die Zeit zum Erhalten der Die Sperre ist kleiner als die Zeitüberschreitungszeit für die Sperrmenge. Dies beweist, dass die Sperre wirksam ist!
Wenn das Schloss erhalten wird, ist die tatsächliche effektive Zeit des Schlüssels gleich der effektiven Zeit minus der Zeit, die zum Erhalten des Schlosses aufgewendet wurde (das in Schritt 3 berechnete Ergebnis).
Wenn mehr als die Hälfte der Maschinen, die die Sperre erhalten, nicht zufrieden sind oder das Sperrzeitlimit nach der Berechnung negativ ist oder andere abnormale Vorgänge vorliegen, versucht das System, alle Instanzen zu entsperren, auch wenn einige Redis-Instanzen nicht gesperrt sind Dies ist überhaupt nicht erfolgreich, wodurch verhindert wird, dass bestimmte Instanzen gesperrt werden, der Client jedoch keine Antwort erhält, was dazu führt, dass die Sperre für einen bestimmten Zeitraum nicht wiederhergestellt werden kann zuverlässige Sperre als Single-Point-Redis.
, die Sie direkt verwenden können.
Brauchen wir Redlock wirklich?
Es gibt tatsächlich eine andere Stimme zu Redlock, geschrieben von Martin Kleppmann (einem Forscher an der Universität Cambridge, der am TRVE DATA-Projekt an der Schnittstelle von Datenbanken und verteilten Systemen beteiligt ist). und Informationssicherheit) Ich habe einmal einen
Blogüber einige Ansichten zu Redlock veröffentlicht. Wenn Sie interessiert sind, können Sie ihn lesen. Redis-Autor Salvatore hat auch einige Antworten auf die Fragen in diesem Artikel gegeben, was sehr interessant ist. Die Hauptpunkte des Blogs des Autors lauten wie folgt: Es gibt nicht mehr als zwei Verwendungsmöglichkeiten für verteilte Sperren:
Effizienz: Durch die Verwendung von Sperren kann vermieden werden, dass dieselbe Arbeit zweimal ausgeführt wird (z. B. einige teure Berechnungen). Wenn die Sperre fehlschlägt und beide Knoten am Ende die gleiche Aufgabe erledigen, führt dies zu einem leichten Kostenanstieg (Sie zahlen AWS am Ende 5 Cent mehr als sonst) oder zu geringfügigen Unannehmlichkeiten (z. B. erhält der Benutzer am Ende dieselbe E-Mail). Benachrichtigung). Richtigkeit: Durch die Verwendung von Sperren wird verhindert, dass gleichzeitig ablaufende Prozesse einander stören und den Systemstatus beschädigen. Wenn die Sperre fehlschlägt und zwei Knoten gleichzeitig dieselben Daten verarbeiten, kommt es zu Dateibeschädigungen, Datenverlust, dauerhafter Inkonsistenz, einer falschen Medikamentendosis an den Patienten oder einem anderen sehr schwerwiegenden Problem.Timing und Systemuhren gehen von gefährlichen Annahmen aus und hängen stark von der Uhr jedes Servers ab. Da sich im System ein GC befindet, wird während des GC der gesamte Server überlastet und die Zeit stagniert, sodass wir nicht stark von der Uhr abhängig sein können.
Kein Token. Der Server stellt nicht jedes Mal ein Token aus, wenn der Client die Sperre erwirbt. Der Server sollte bei jedem Vorgang überprüfen, ob das Token des Clients mit dem aktuellen Token auf dem Server übereinstimmt, um die Betätigung der Sperre zu erschweren.
Der Autor konzentriert sich hauptsächlich auf die oben genannten Standpunkte. Bei Interesse wird empfohlen, den Originalartikel zu lesen.
! !
Das obige ist der detaillierte Inhalt vonEine kurze Analyse der Sperren in Redis. Lassen Sie uns über Redlock (Redis Distributed Lock) sprechen.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!