java 之分布式锁-redis-Redisson-Zookeeper 不同方式实现

Redis 实现分布式锁

原理
采用Setnx 命令 为 key 设置指定的值,设置成功,返回 1 。 设置失败,返回 0

如何考虑避免死锁问题
设置锁的过期时间,避免死锁问题

Redis key过期了,但是业务还没有执行完毕如何处理
采用续命设计:
获取锁成功之后,开启一个续命的线程,检测如果当前业务逻辑还没有执行完毕的情况下,应该不断的延迟过期key的时间,防止死锁 ,限制次数,并且回滚事物

Redis集群,主节点宕机如何处理
Redis集群数据同步改为同步的形式;效率偏低

Redisson实现分布式锁

原理
1 多个jvm同时的在redis中写入一个相同的key(1.使用lua脚本调用redisapi),
谁能够写成功谁就获取锁成功。

2.如果写入key成功,会单独开启一个看门狗的线程(续命定时
任务线程) 默认的情况下每隔10s时间不断续命延迟。

Redis集群,主节点宕机如何处理?
用Redlock 红锁
原理:
1 构建Redis集群没有主从之分,Redis节点都可能为主节点;
2 获取锁的时候,jvm向多个不同的redis服务器端去抢锁,只要有一半的redis服务器执行成功,则表示获取锁成功。

Zookeeper实现分布式锁

原理
1 多个jvm同时在zk上创建一个临时节点/lockPath,最终只能够有一个jvm创建临时节点成功
2 获取锁失败的jvm ,可以采用重试,重试无果 就设置一个事件监听,然后进入到阻塞状态

如何考虑避免死锁问题

zk客户端宕机:服务端会自动断开连接,删除该临时节点

zk 服务端宕机:没有获取超时时间的线程阻塞并设置一个超时时间。

业务超时,一直不释放锁如何处理?
采用续命设计:
获取锁成功之后,开启一个续命的线程,检测如果当前业务逻辑在一定时间内还没执行完就主动释放锁,同时事务回滚

如何避免分布式锁羊群效应问题
基于临时顺序编号节点实现zk锁,当前jvm创建临时顺序节点编号是最小的时候,代表获取锁成功,如果不是最小的就进入阻塞状态,订阅到我们上一个节点的事件通知

主节点宕机
zk同步数据是同步的,
1.先比较zxid,zxid 谁最大谁就是为leader角色;
2.如果zxid相等的情况下,则比较myid myid 谁最大 谁就是为
领导角色。

你可能感兴趣的:(Java分布式解决方案,java)