目前主流的分布式锁都是依靠第三方存储介质的一致性保障实现的,比如常见的
- 基于关系型数据库(如MySql)的排它锁实现的分布式锁
- 基于分布式协调系统(Zookeeper临时节点+通知事件)实现的分布式锁
- 基于Redis, setNx特性实现的分布式锁
基于Redis的分布式锁
其中应用最广泛的应该是Redis的分布式锁,它对比前两者都有着很大的优势
- 巨大的写性能优势,特别是对比MySql
- 对比于Zookeeper,Redis更加普及。很少会团队专门为分布式锁引入Zookeeper
弊端
不过常规的基于Redis实现的分布式锁,因为Redis作为缓存数据库的特性,有着如下的弊端:
- 锁超时时效引起的问题
- 锁释放非原子性引发更多的问题
- Redis故障转移时数据丢失引起的问题
图中合并了前两个错误场景,第三个场景造成的后果与场景一类似
解决超时问题
其中概率最高的问题,就是超时续期的问题。
目前普遍的解决方案:
守护线程续期解决方案
升级版
上面那个解决方案,每开一个锁就需要打开一个守护线程。高并发的情况下,很容易因为打开了过多的线程而使CPU负载标高,效率低浪费资源
- 使用注册表注册成功持有锁的锁对象
- 始终保持一个线程轮询注册表进行续期
在优化一下可以使用弱引用等监控GC,来回收没有正确释放的锁。
解决故障转移问题
可以结合作者提出的红锁方案
RedLock核心思想是使用多个数据源,超过半数的数据源成功上锁才视为成功,比如用五个数据源时有两个数据源故障,也不影响锁的正确性