分布式锁
2021-11-12 12:15:10 0 举报
AI智能生成
针对于Java体系的,几种常见分布式锁的使用场景
作者其他创作
大纲/内容
Zookeeper
方式
临时节点+事件通知
过程
多个Jvm在ZK上创建临时节点,成功的则,获取到锁,执行业务逻辑
失败的则创建该节点的监听,一旦Close()该方法后,重新竞争锁资源
问题
羊群效应
说明
多个获取锁失败的Jvm,监听节点后,服务端ZK唤醒的成本比较大
优化
采用临时顺序节点,如果当前临时节点顺序编号是最小的话,则获取锁成功
如果获取锁失败的话,则订阅上个编号的节点,这样的话,释放锁之后,就会依次进行通知了
zkleader宕机之后,如何避免客户端死锁?
1.zk客户端会收到zkserver端断开长连接监听,在时候就会主动唤醒起来,从新进入到获取锁的状态
2.当前线程设置一个阻塞时间 60 120s 不会一直阻塞 避免死锁的问题
zk客户端宕机之后,如何避免死锁?
当zk客户端宕机之后一直没有给zkserver发送续约,Zkserver端认为该节点宕机,自动将该节点移除
说明
其实上面这两点存在问题-余胜军-分布式锁
框架
Curator
特点
1. 从缓存中查找是否已经创建分布式锁,如果已经创建了分布式锁则直接复用(具有可重入性)
2.创建分布式锁成功后,则将自身线程缓存到集合中
读写锁
上面锁的实现更多的是互斥锁,因此性能较低,可以使用读写锁
Redis
1.Setnx设置超时时间
2.业务没有执行完毕,则给当前锁续命,并且设置续命次数,多次后还没执行完毕,则认为超时,释放锁
框架
Redisson
续命
默认续命三次,每次10S,业务超时时间=30s
利用Lua脚本设置Hash值
Hash中属性value默认为1,每次锁重入的话,则value+1
问题
释放锁的时候,怎么可以不释放其它人创建的锁?
SetNx加锁的时候,key==关键标识;value==自身唯一的标识即可
jvm01连接到主的redis 做setnx操作的时候,异步将数据同步给从redis;意味着jvm01获取锁成功,正好在这时候主redis宕机了,redis集群自动开启哨兵机制选举,就会选举剩余从节点中某个redis为主redis,就会导致两个jvm获取锁成功(Redis异步同步导致该问题)
1.将Redis异步同步方式改成同步的方式,效率太低
2.Redisson红锁
获取锁的时候,当前客户端(JVM)会向多个不同的redis服务器端执行
Setnx操作,只要有一半的redis服务器执行成功,则表示获取锁成功
Setnx操作,只要有一半的redis服务器执行成功,则表示获取锁成功
特性
重试
超时
续命
性能优化
高可用
公平性
0 条评论
下一页