Redis Distributed Lock:
1. Implementierungsprinzip
Verwenden Sie den Set-Befehl in Redis, um eine verteilte Sperre zu implementieren.
Ab Redis-Version 2.6.12 kann set die folgenden Parameter verwenden:
SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]
EX Sekunde: Stellen Sie die Ablaufzeit des Schlüssels auf Sekunden ein. Die Wirkung des SET-Schlüsselwerts EX Sekunde entspricht dem SETEX-Schlüsselwert Sekunden.
PX Millisekunde: Stellen Sie die Ablaufzeit des Schlüssels auf Millisekunden Millisekunden ein. Der Millisekundeneffekt des SET-Schlüsselwerts von PX entspricht dem Millisekundenwert des PSETEX-Schlüssels.
NX: Der Schlüssel wird nur gesetzt, wenn der Schlüssel nicht existiert. Die Wirkung des SET-Schlüsselwerts NX entspricht dem SETNX-Schlüsselwert.
XX: Legen Sie den Schlüssel nur fest, wenn der Schlüssel bereits vorhanden ist.
Rückgabewert:
SET gibt nur OK zurück, wenn der Einstellungsvorgang erfolgreich abgeschlossen wurde.
Wenn NX oder XX festgelegt ist, der Einstellungsvorgang jedoch nicht ausgeführt wird, weil die Bedingungen nicht erfüllt sind, gibt der Befehl eine NULL-Massenantwort zurück.
Befehl:
> SET key value EX ttl NX
Die allgemeine Idee ist:
(a) SET lock currentTime+expireTime EX 600 NX, verwenden Sie set, um den Sperrwert festzulegen und Ablaufdatum festlegen Die Zeit beträgt 600 Sekunden. Bei Erfolg wird die Sperre erworben. (b) Wenn der Knoten nach dem Erwerb der Sperre offline geht, läuft der Sperrwert automatisch ab (c) Wenn die Sperre aufgehoben wird, löschen Sie den Sperrschlüsselwert mit del.
2. Vorteile
Hohe Leistung, Redis kann beibehalten werden und Daten gehen nicht so leicht verloren.
Die Redis-Cluster-Methode verbessert die Stabilität.
3. Nachteile
Bei Verwendung der Redis-Master-Slave-Umschaltung können einige Daten verloren gehen.
4. Open-Source-Implementierung
Open-Source-Implementierung der Python-Version: python-redis-lock.
Die spezifische Implementierungsmethode der verteilten Redis-Sperre:
Die Methode zum Sperren und Entsperren:
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"; private static final Long RELEASE_SUCCESS = 1L; /** * 尝试获取分布式锁 * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 超期时间 * @return 是否获取成功 */ public Boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) { Jedis jedis = this.jedisPool.getResource(); String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } /** * 释放分布式锁 * @param lockKey 锁 * @param requestId 请求标识 * @return 是否释放成功 */ public Boolean releaseDistributedLock(String lockKey, String requestId) { Jedis jedis = this.jedisPool.getResource(); String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; }2. Spezifische Anwendungen
try{ String requestId = UUID.randomUUID().toString(); Boolean flag = tryGetDistributedLock(lock,requestId,1000); int n = 0; while(!flag){ //如果没有获取锁,可以尝试下一个lock,如果都没有,则尝试 n 次,退出 ... if(n++>5){ throw new Exception("尝试获取锁失败");} ... } if(!flag){ throw new Exception("尝试获取锁失败"); } }catch(){ }finally{ releaseDistributedLock(lock,requestId); }Weitere Informationen zu Redis finden Sie in der Spalte
Tutorial zur Redis-Nutzung
!Das obige ist der detaillierte Inhalt vonSo implementieren Sie die verteilte Redis-Sperre. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!