Heim > Backend-Entwicklung > Golang > Verwalten Sie verteilte Sperren effizient mit Redis: Eine Go-basierte Lösung

Verwalten Sie verteilte Sperren effizient mit Redis: Eine Go-basierte Lösung

DDD
Freigeben: 2024-10-21 06:17:02
Original
497 Leute haben es durchsucht

Efficiently Manage Distributed Locks with Redis: A Go-Based Solution

Verteilte Sperren sind in Systemen unerlässlich, in denen mehrere Prozesse um gemeinsame Ressourcen konkurrieren. Unabhängig davon, ob es sich um Datenbankzugriffe oder Dateiänderungen handelt, ist die Vermeidung von Race Conditions von entscheidender Bedeutung. In diesem Artikel werde ich eine Redis-basierte verteilte Sperrimplementierung in Go vorschlagen, die zum Synchronisieren von Aufgaben auf mehreren Servern verwendet werden kann.

Die größte Herausforderung beim verteilten Sperren besteht darin, sicherzustellen, dass Sperren im Fehlerfall freigegeben werden, Deadlocks zu vermeiden und Konflikte zu verwalten. Unsere in Go integrierte Redis-Sperrbibliothek löst diese Probleme, indem sie sicherstellt, dass Sperren automatisch freigegeben werden und Anfragen in der Warteschlange effizient verwaltet werden.

Diese Bibliothek verfügt über mehrere Funktionen, die das verteilte Sperren einfach und zuverlässig machen sollen:

  • Automatischer Sperrenablauf: Sperren werden nach einer Zeitüberschreitung automatisch freigegeben, wenn sie nicht explizit entsperrt werden, wodurch Deadlocks verhindert werden.
  • Warteschlangenmechanismus: Konkurrierende Anfragen werden in die Warteschlange gestellt, um sicherzustellen, dass ihnen der Zugriff nach dem Prinzip „Wer zuerst kommt, mahlt zuerst“ gewährt wird.
  • Ereignisabonnement: Die Bibliothek nutzt den Pub/Sub-Mechanismus von Redis, um auf Schlüsselablauf- oder Löschereignisse zu warten und so eine effiziente Sperrübergabe sicherzustellen. Beginnen wir nun damit, in die Komponenten einzutauchen und zu verstehen, wie sie auf hoher Ebene funktionieren:

Die Rolle von LockManager

Der LockManager spielt eine Schlüsselrolle bei der Verwaltung des Lebenszyklus von Sperren, der Abwicklung der Kommunikation mit Redis und der Koordinierung der Sperranfragen. Es ist verantwortlich für:

  • Sperren erwerben: Es verarbeitet Anfragen zum Erwerb von Sperren für bestimmte Schlüssel in Redis und stellt sicher, dass jeweils nur ein Prozess oder Thread eine Sperre für einen bestimmten Schlüssel halten kann.
  • Sperranforderungen in die Warteschlange stellen: Wenn eine Sperre bereits von einem anderen Prozess gehalten wird, fügt der LockManager die Sperranforderung einer Warteschlange hinzu und wartet auf Redis-Benachrichtigungen, die angeben, dass die Sperre freigegeben wurde oder abgelaufen ist.
  • Sperren freigeben: Es stellt sicher, dass Sperren korrekt freigegeben werden, indem überprüft wird, ob der Prozess, der versucht, die Sperre freizugeben, derjenige ist, der sie hält (basierend auf dem eindeutigen Sperrwert).
  • Abhören von Keyspace-Ereignissen: Der Manager abonniert Redis-Keyspace-Ereignisse wie Schlüsselablauf oder -löschung, um zu wissen, wann Sperren freigegeben werden, und um wartende Prozesse zu benachrichtigen.
  • Verwaltung mehrerer Sperren: Der LockManager kann mehrere Sperranforderungen gleichzeitig verarbeiten und eignet sich daher für verteilte Systeme mit vielen gleichzeitigen Prozessen. Die Lock-Funktion von LockManager nimmt einen Kontext und einen Schlüssel entgegen, versucht, die Sperre zu erhalten, stellt Anforderungen in die Warteschlange, die die Sperre nicht sofort erhalten können, und gibt eine Lock-Struktur zurück, über die wir in späteren Abschnitten sprechen werden.
func (manager *lockManager) Lock(c context.Context, key string, ttl time.Duration) Lock {
    ...
}
Nach dem Login kopieren
Nach dem Login kopieren

Die Sperrfunktion dient dazu:

  • Generieren Sie für jeden Sperrversuch einen eindeutigen Wert.
  • Stellen Sie sicher, dass nur der Prozess/Thread, der die Sperre erhält, diese freigeben kann.
  • Verwenden Sie die atomaren Operationen von Redis, um die Sperre sicher zu erhalten.
  • Stellen Sie Sperranfragen in die Warteschlange und achten Sie auf wichtige Ablaufereignisse über Redis Pub/Sub.

Das Lock-Objekt

Sobald Sie das Sperrobjekt erhalten, haben Sie Zugriff auf die Funktionen „Entsperren“ und „Warten“, die für die Arbeit innerhalb des Objekts konzipiert sind. Diese Funktionen sind entscheidend für die Verwaltung des Lebenszyklus eines Schlosses und die Handhabung des Ergebnisses seines Erwerbs.

Entsperrfunktion
Die Unlock-Funktion ist dafür verantwortlich, die Sperre aufzuheben, wenn der Thread oder Prozess mit der Ressource fertig ist. Dadurch wird sichergestellt, dass nur der Thread oder Prozess, der die Sperre besitzt (d. h. derjenige, der den richtigen Sperrwert enthält), diese freigeben kann. Lassen Sie uns zusammenfassen, wie das funktioniert:

func (lock *Lock) Unlock() error {
    return lock.manager.releaseLock(lock.key, lock.value)
}
Nach dem Login kopieren

Wartefunktion
Mit der Wait-Funktion kann der Aufrufer warten, bis das Ergebnis des Versuchs, die Sperre zu erhalten, verfügbar ist. Dies ist besonders nützlich in Fällen, in denen ein Sperrenkonflikt auftritt und ein Prozess in der Warteschlange steht und darauf wartet, dass die Sperre verfügbar wird.

func (lock *Lock) Wait() result {
    return <-lock.resultChan
}
Nach dem Login kopieren

Erklärung:
Kanalbasiertes Warten: Das Lock-Objekt verfügt über einen resultChan-Kanal, der zur Kommunikation des Ergebnisses des Lock-Akquisitionsversuchs verwendet wird. Wenn die Sperre erworben wird (oder fehlschlägt), wird das Ergebnis über diesen Kanal gesendet. Die Wait-Funktion blockiert einfach, bis ein Ergebnis verfügbar ist.

Nicht blockierende Ausführung: Wenn ein Prozess versucht, mit Lock() eine Sperre zu erlangen, muss er nicht den gesamten Thread blockieren, während er wartet. Stattdessen kann Wait() aufgerufen werden, das nur blockiert, bis ein Ergebnis vorliegt. Der resultChan ermöglicht eine asynchrone Kommunikation zwischen der Sperrlogik und dem aufrufenden Code, wodurch das Design nicht blockierend wird.

Ergebnisobjekt: Die Funktion gibt ein Ergebnisobjekt zurück:

func (manager *lockManager) Lock(c context.Context, key string, ttl time.Duration) Lock {
    ...
}
Nach dem Login kopieren
Nach dem Login kopieren

Zusammenfassend lässt sich sagen, dass die Hauptmerkmale dieser Bibliothek ihre Fähigkeit sind, hohe Parallelität zu bewältigen und gleichzeitig sicherzustellen, dass Sperren rechtzeitig freigegeben werden. Durch die Verwendung der TTL-Funktion von Redis werden Sperren automatisch freigegeben, wenn der Prozess, der die Sperre hält, fehlschlägt.

Redis-basierte verteilte Sperren sind eine leistungsstarke Lösung für die Verwaltung gemeinsam genutzter Ressourcen in verteilten Systemen. Diese Go-Bibliothek erleichtert die Implementierung robuster Sperrmechanismen, die skalierbar, effizient und fehlertolerant sind. Schauen Sie sich das Repository hier an und beginnen Sie noch heute mit dem Aufbau zuverlässiger verteilter Systeme!

Möchten Sie einen Beitrag leisten oder haben Sie Fragen? Fühlen Sie sich frei, Probleme zu öffnen oder Anfragen im GitHub-Repository zu stellen.

Das obige ist der detaillierte Inhalt vonVerwalten Sie verteilte Sperren effizient mit Redis: Eine Go-basierte Lösung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage