redis分布式锁

1、->setnx test:code true
do something
->del test:code
问题:在执行do something中执行中出现异常,导致del没有执行,则锁永远无法释放。

Redis 2.8 版本中作者加入了 set 指令的扩展参数,使得 setnx 和 expire 指令可以一起执行
2、->set test:code ture ex 5 nx
do something
->del test:code
问题1:当执行do something的时间过长,超过了设置的过期时间,则这个时候线程1还没有执行完,锁已经释放了,可能导致其他线程获取到了锁。

延伸:在执行del的时候需要进行对比value的值。
因为:第一个线程执行时间过长,还没执行完锁已过期,此时第二个线程进入了锁,还没执行完时第一个线程终于执行到了del指令,此时如果不对比value就会删掉第二个锁,这样锁就会彻底乱掉。 加上对比value的指令可以防止彻底乱掉,但是无法防止第一次的打乱

使用LUA脚本来编写命令,是为了能够不间断的执行。

问题:在集群模式下还是产生问题。比如在哨兵模式下,主节点挂掉时,从节点代之。客户端上没有明显感知,原先客户端在主节点上申请成功了一把锁,但是这把锁还没来的及同步到从节点,主节点挂掉了。然后从节点变成了主节点,这个新的节点内部就没有这个锁,所以当另一个客户端请求加锁,就成功了。不安全性由此出来了。

为了解决这个问题:RedLock算法

为了使用RedLock需要提供多个redis实例。这些实例之间独立没有主从关系,加锁时,它会向过半节点发送 set(key,value,nx=ture,ex=…)指令,只要过半节点 set成功,那就认为加锁成功,释放锁时,需要向所有节点发送 de指令,
不过 Redlock 算法还需要考虑出错重试、时钟漂移等很多细节问题,同时因为 Redlock 需要向多个节点进行读写,意味着相比单实例 Redis 性能会下降一些。

https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html

上一篇:GBase 8c Raft协议学习(一)


下一篇:MACD制作方法