redis死锁处理

参见:https://redis.io/commands/setnx#handling-deadlocks
Handling deadlocks

When this happens we can’t just call DEL against the key to remove the lock and then try to issue a SETNX, as there is a race condition here, when multiple clients detected an expired lock and are trying to release it.

错误示例:
C1 and C2 read lock.foo to check the timestamp, because they both received 0 after executing SETNX, as the lock is still held by C3 that crashed after holding the lock.
C1 sends DEL lock.foo
C1 sends SETNX lock.foo and it succeeds
C2 sends DEL lock.foo
C2 sends SETNX lock.foo and it succeeds
ERROR: both C1 and C2 acquired the lock because of the race condition.

正确做法:
1、setnx失败
2、get检查锁是否过期
3、未过期睡眠一段时间重复前述步骤
4、已过期使用GETSET (原子操作,返回旧值,可检查key是否已被其他客户端重新设置过期时间)
5、若GETSET值已过期则获得锁
6、若GETSET值未过期,说明其他客户端更快地获得了锁,需重复上述步骤。重新设置的过期时间影响不大。
In order to make this locking algorithm more robust, a client holding a lock should always check the timeout didn’t expire before unlocking the key with DEL because client failures can be complex, not just crashing but also blocking a lot of time against some operations and trying to issue DEL after a lot of time (when the LOCK is already held by another client)

你可能感兴趣的:(Redis)