Verteilte Sperren haben im Allgemeinen drei Implementierungsmethoden: 1. Datenbankoptimistische Sperre 2. Redis-basierte verteilte Sperre 3. ZooKeeper-basierte verteilte Sperre;
Hier stellen wir die Implementierung verteilter Sperren basierend auf Redis vor.
Eigenschaften verteilter Sperren:
Zuverlässigkeit. Um sicherzustellen, dass verteilte Sperren verfügbar sind, müssen wir zunächst mindestens sicherstellen, dass die Sperrimplementierung gleichzeitig die folgenden vier Bedingungen erfüllt:
Gegenseitige Exklusivität . Es kann immer nur ein Client die Sperre halten.
Es wird kein Deadlock auftreten. Selbst wenn ein Client abstürzt, während er die Sperre hält, ohne sie aktiv zu entsperren, ist gewährleistet, dass andere Clients ihn anschließend sperren können.
hat Fehlertoleranz. Solange die meisten Redis-Knoten normal laufen, kann der Client sperren und entsperren.
Um die Glocke zu lösen, müssen Sie die Glocke binden. Das Sperren und Entsperren muss vom selben Client durchgeführt werden. Der Client selbst kann die von anderen hinzugefügte Sperre nicht entsperren.
Abhängigkeiten von Code-Implementierungskomponenten
Zuerst müssen wir Jedis-Open-Source-Komponenten über Maven einführen und den folgenden Code zur pom.xml-Datei hinzufügen:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
Korrekte Haltung zum Sperrcode
Reden ist günstig, zeig mir den Code. Zeigen Sie zuerst den Code und erklären Sie dann langsam, warum er auf diese Weise implementiert wird:
public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; /** * 尝试获取分布式锁 * @param jedis Redis客户端 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功 */ public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } }
Wie Sie sehen, benötigen wir zum Sperren nur eine Codezeile: jedis.set(String key, String value, String nxxx , String expx, int time ), diese set()-Methode hat insgesamt fünf formale Parameter:
Der erste ist der Schlüssel. Wir verwenden den Schlüssel als Sperre, da der Schlüssel eindeutig ist.
Der zweite Punkt ist der Wert, den wir weitergeben. Viele Kinder verstehen möglicherweise nicht, dass ein Schlüssel als Schloss dient. Der Grund dafür ist, dass, wenn wir oben über Zuverlässigkeit gesprochen haben, die verteilte Sperre die vierte Bedingung erfüllen muss, um die Glocke zu entsperren, und die Person, die die Glocke hält, die Person sein muss, die die Glocke gebunden hat. Durch Zuweisen des Werts zu requestId wissen wir, welche Anfrage vorliegt Beim Entsperren können Sie dann eine Basis hinzufügen. requestId kann mit der Methode UUID.randomUUID().toString() generiert werden.
Der dritte ist nxxx, was SET IF NOT EXIST bedeutet, das heißt, wenn der Schlüssel nicht existiert, führen wir die Set-Operation aus, nein Operation wird ausgeführt;
Der vierte Parameter ist PX, was bedeutet, dass wir diesem Schlüssel eine Ablaufeinstellung hinzufügen möchten. Die spezifische Zeit wird durch den fünften Parameter bestimmt.
Der fünfte Parameter ist die Zeit, die dem vierten Parameter entspricht und die Ablaufzeit des Schlüssels darstellt.
Im Allgemeinen führt die Ausführung der oben genannten set()-Methode nur zu zwei Ergebnissen: 1. Derzeit ist keine Sperre vorhanden (der Schlüssel ist nicht vorhanden). Führen Sie dann den Sperrvorgang aus und legen Sie einen Gültigkeitszeitraum für fest lock und value repräsentiert den gesperrten Client. 2. Die Sperre ist bereits vorhanden, es wird kein Vorgang ausgeführt.
Unser Sperrcode erfüllt die drei in unserem Abschnitt „Zuverlässigkeit“ beschriebenen Bedingungen. Zunächst fügt set() den NX-Parameter hinzu, der sicherstellt, dass die Funktion nicht erfolgreich aufgerufen wird, wenn der Schlüssel bereits vorhanden ist, d. h. nur ein Client kann die Sperre halten, was den gegenseitigen Ausschluss erfüllt. Zweitens: Da wir eine Ablaufzeit für die Sperre festgelegt haben, wird die Sperre automatisch entsperrt (dh der Schlüssel wird gelöscht), selbst wenn der Sperrhalter später abstürzt und nicht entsperrt wird, da die Ablaufzeit erreicht ist und kein Deadlock vorliegt wird auftreten. Da wir schließlich requestId einen Wert zuweisen, der die Identifikation der gesperrten Clientanforderung darstellt, kann beim Entsperren des Clients überprüft werden, ob es sich um denselben Client handelt. Da wir nur das Szenario der eigenständigen Bereitstellung von Redis betrachten, werden wir die Fehlertoleranz vorerst nicht berücksichtigen.
Das obige ist der detaillierte Inhalt vonWie lang ist das Timeout für die verteilte Redis-Sperre?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!