Redis如何实现分布式锁(一)
2019-05-06 本文已影响1人
裘马轻狂大帅
分布式锁一般有三种实现方式:
1. 数据库乐观锁;
2. 基于Redis的分布式锁;
3. 基于ZooKeeper的分布式锁。
首先,为了确保分布式锁可用,至少要确保锁的实现同时满足以下四个条件:
互斥性。在任意时刻,只有一个客户端能持有锁。
不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。
redis实现分布式锁的相关问题,有几个问题先要了解一下:
1.为什么不直接使用expire设置超时时间,而将时间的毫秒数其作为value放在redis中?
如下面的方式,把超时的交给redis处理:
if (conn.setnx(lockKey) == 1) {
conn.expire(lockKey, lockExpire);
这种方式貌似没什么问题,但是假如在setnx后,redis崩溃了,expire就没有执行,结果就是死锁了。锁永远不会超时。
2.多台机器同时向redis发出set 请求,会不会存在并发等问题?
redis是不会存在并发问题的,因为是单进程的,再多的command都是1 to1 执行的。我们使用的时候,可能会出现的并发问题都是多个命令组才会出现,比如get和set这一对。