分布式协调场景
集群的缓存失效,让一个请求更新缓存即可,怎么做?
高并发缓存过期,所有请求都从数据库中读取数据更新缓存?
如何解决这个问题,我们需要一把锁
锁具有什么特点
排他性:只有一个线程获取到锁,保证在在不同的节点的不同线程互斥。
阻塞性:资源未被释放,收到阻塞。等待释放后,继续抢锁。
可重入性 :线程获取锁后,后续是否可重复获取该锁。
锁超时:和本地锁一样支持超时锁,防止死锁。
支持阻塞和非阻塞:和ReentrantLock一样支持lock 和tryLock
支持公平锁和非公平锁:公平锁的意思是按照请求加锁的顺序执行,非公平锁就是顺序的。
高效,可用:加锁和解锁需要高效,同时也要保证高效防止分布式锁失效,可以增加降级处理。
何为分布式锁?
在分布式系统中,需要相互协调服务之间的动作。如果不同的系统或是同一个系统不同主机之间,去访问共享资源或同一个
资源的时候,往往需要通过互斥性来防止彼此之间的干扰,保证资源的一致性。在这个时候,就需要一把分布式锁。
具有排他性的其他技术
- 文件系统
- 数据库(乐观锁) 主键,唯一约束,for update
- 缓存 redis:=>senx
- zookeeper 类似于文件系统
- 自研发的:如goole Chubby
基于数据库实现分布式锁
- 性能较差,容易出现单点故障
- 锁没有失效时间,容易死锁
基于缓存实现分布式锁
- 实现复杂
- 存在死锁(或短时间死锁)的可能
基于zookeeper实现分布式锁
- 实现相对简单
- 可靠性能高
- 性能较好
zookeeper分布式锁:
阻塞性:通过JDK栅栏实现
可重入:计数器实现。
非公平锁:
公平锁:
个人gitgub:https://github.com/wywhdgg/dzb-distributed-lock
curator:https://github.com/apache/curator
zkClient:https://github.com/yfcchilly/zkclient
有三种实现:redis,zkClient,curator 仅供大家参考。
Apache curator 开源项目:
- 解决watch注册一次就会失效问题。
- 提供的API更加简单
- 提供更多解决方案并且实现简单。如:分布式锁
- 提供常用的ZK工具类
- 编程风格更舒服