两大类分布式锁:类自旋式的分布式锁 mysql redis ; 事件通知后续锁的变化 zookeeper etcd
redis:单线程的串行的 本地方法setnx+timeout
发布订阅模式,阻塞队列+超时
zookeeper:
Zookeeper集群是一个主从集群,它一般是由一个Leader(领导者)和多个Follower(跟随者)组成。此外,针对访问量比较大的Zookeeper集群,还可新增Observer(观察者)。Zookeeper集群中的三种角色各司其职,共同完成分布式协调服务。下面我们针对Zookeeper集群中的三种角色进行简单介绍。
1.Leader
它是Zookeeper集群工作的核心,也是事务性请求(写操作)的唯一调度和处理者,它保证集群事务处理的顺序性,同时负责进行投票的发起和决议,以及更新系统状态。
2.Follower
它负责处理客户端的非事务(读操作)请求,如果接收到客户端发来的事务性请求,则会转发给Leader,让Leader进行处理,同时还负责在Leader选举过程中参与投票。
3.Observer
它负责观察Zookeeper集群的最新状态的变化
jvm锁: cas自旋锁
ZooKeeper和Reids做分布式锁的区别?
Reids:
- Redis只保证最终一致性,副本间的数据复制是异步进行(Set是写,Get是读,Reids集群一 般是读写分离架构,存在主从同步延迟情况),主从切换之后可能有部分数据没有复制过去可能会「丢失锁」 情况,故强一致性要求的业务不推荐使用Reids,推荐使用zk。
- Redis集群各方法的响应时间均为最低。随着并发量和业务数量的提升其响应时间会有明显上升(公网集群影响因素偏大),但是极限qps可以达到最大且基本无异常
ZooKeeper
- 使用ZooKeeper集群,锁原理是使用ZooKeeper的临时顺序节点,临时顺序节点的生命周期在Client与集群的Session结束时结束。因此如果某个Client节点存在网络问题,与ZooKeeper集群断开连接 ,Session超时同样会导致锁被错误的释放(导致被其他线程错误地持有) , 因此ZooKeeper也无法保证完全- -致。
- ZK具有较好的稳定性;响应时间抖动很小,没有出现异常。但是随着并发量和业务数量的提升其响应时间和qps会明显下降。
总结:
- Zookeeper每次进行锁操作前都要创建若干节点,完成后要释放节点,会浪费很多时间;
- 而Redis只是简单的数据操作,没有这个问题。