redis分布式锁问题

建立redis集群,作为分布式锁。

redis分布式锁问题

分布式锁要解决的是分布式环境下,并行相同代码的加锁功能;了解过redis分布式锁的人肯定知道,一开始redis作为分布式锁用的是setnx,再这基础上设置个定时过期时间,但这种方式有什么问题呢?

首先是原子性问题,setnx+过期时间这两个操作必须是原子性的,所以这可以用lua脚本解决

再然后是释放锁的时机该如何定?
Redisson是如何解决上述问题的呢?

它对代码进行了精简的封装,我们的使用非常简单,甚至我们不用主动设置过期时间

它设计了个watch dog看门狗,每隔10秒会检查一下是否还持有锁,若持有锁,就给他更新过期时间30秒;通过这样的设计,可以让他在没有释放锁之前一直持有锁,哪怕宕机了,也能自动释放锁

而不能获得锁的客户端则是不断循环尝试加锁

通过记录锁的客户端id,可以把它设计成可重入锁

redis分布式锁问题

存在问题

redis作为分布式锁再大多数情况下是没问题的,但是我们知道CAP原理,一致性,可用性,分区容错性

在redis分布式架构中,我们其实保证的是AP模型

没有保证一致性,假如:

当持有锁的节点挂掉之前,还没来得及将锁同步给从节点,

从节点接替主节点进行读写,此时新的主节点没有持有该锁,那么其他想要获取该锁的服务也可以获取到该锁,导致了重复锁的问题。

想彻底解决该问题,很难,除非修改源码,进行二次开发。必须保证,加锁时,主节点与从节点同时加锁成功。

一般来讲这种情况发生的概率是很小的,看你系统的规模而定,我觉得像阿里这种规模就应该不会用redis来作为分布式锁了

类似的zookeeper集群出现脑裂,也可能会导致出现该重复锁问题。
客户端1注册一个临时有序节点,拿到锁,运行过程中,客户端1与zookeeper网络断开,自动删除该节点。此时客户端2会拿到锁,但其实客户端1正在运行程序。

CP模型的分布式锁可以用zookeeper,可能性能略低于redis,但能保证安全,可以提供顺序锁等额外功能,但不能完全解决重复锁问题。

原则上说,zookeeper更适合做分布式锁,但本身适用的场景为3,5台节点。redis不适合做分布式锁,本身是做缓存的,但大规模集群能抗住高并发。对于高并发场景下,zookeeper不适合,也只能选用redis了。