经过线上实战的redis 分布式锁与zookeeper分布式锁区别_个人渣记录仅为自己搜索用的博客-优快云博客 pom 依赖 <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-examples</artifactId> <version>${curator-version}</version> </dependency>
分布式锁:
用例:
*参与者: 客户端,服务端.
* 用例目的: 客户端申请加锁
* 核心场景:
# 多个线程在一个客户端里申请加锁.
* 过程描述:
# 客户端向服务端某个队列增加一个节点
# 服务端返回队列头节点
# 客户端判断头节点是否是自己添加的那个节点.
# 是,加锁成功. 处理业务,删除头节点.
# 否, 监听下一个节点,等待服务端通知.
异常case:
# 服务端回调通知失败, 自己需要定时查询服务端头节点是不是自己.
# 客户端删除头节点失败 .
InterProcessMutex实现
1.本地可重入业务, lockData.lockCount.incrementAndGet();
2. 组合 LockInternal 实现远端分布式加锁
2.1 再依赖内部 StandardLockInternalsDriver
createsTheLock
getsTheLock 并返回预测PredicateResults结果. 监听的下一个节点
// 锁公平性的核心逻辑
// 由InterProcessMutex的构造函数可知,maxLeases为1,即ourIndex为0,才能持有锁,或者说该线程创建的临时顺序节点激活了锁
// Zookeeper的临时顺序节点特性能保证跨多个JVM的线程并发创建节点时的顺序性,越早创建临时顺序节点成功的线程会更早地激活锁或获得锁
boolean getsTheLock = ourIndex < maxLeases;
// 由InterProcessMutex的构造函数可知,maxLeases为1,即ourIndex为0,才能持有锁,或者说该线程创建的临时顺序节点激活了锁
// Zookeeper的临时顺序节点特性能保证跨多个JVM的线程并发创建节点时的顺序性,越早创建临时顺序节点成功的线程会更早地激活锁或获得锁
boolean getsTheLock = ourIndex < maxLeases;
利用了 1. temp 节点,2.和childNode 队列,
3.自旋等待 用来解决通知 timeOut.
关键操作: 当首节点不是自己的时候,监听下一个节点.( 性能比较差的方案是监听整个节点.)
异常处理: getData(下一个节点) 抛 noneNode
缺点:自旋时间=获取timeOut时间
缺点:本地jvm不事先lock
进阶: watch 的触发.
对/root/child add .不会触发/root 的 watch
对比 redis的
1.setnx 法
2.lpush ,lindex 法
选举:
LeaderLatch:
LeaderSelector: 本质上是利用了curator 的分布式锁 mutux + 死循环.
LeaderSelector 相比LeaderLatch 允许获取 master 会,回调lisener,抛错.