- Zookeeper的分布式事务锁
- 首先,zk下有个locker持久节点,持久节点下可以创建多个临时节点node_n。当客户端期望获得分布式锁的时候,他会在locker下通过create()方法创建一个临时节点node_n
- 然后,客户端通过getChildren(“locker”)方法获取到当前locker下的所有临时节点
- 接下来开始判断,自己创建的node_n节点是否是所有节点中最小的,如果是,则获取到锁,如果不是,则创建一个watcher监听,来监听比自己node_n小一级的临时节点
注:之所以只监听比自己小的node_n节点,而不是全部节点的原因是,若是全部监听,当某个节点被使用完毕删除后,当前node不知道此节点是否只自己的之前节点,此时locker下的所有临时节点都会被全部唤醒,一起去抢节点,极易造成阻塞
4.当客户端监听到比自己小的node_n节点被释放了以后,就会再调用一次getchildren方法,获取到当前的所有node临时节点,然后再比较一次,若是发现自己是最小节点,则获得锁,若依旧不是,则继续重复上述行为
- Zookeeper的全局一致性
接下来我就产生了一个问题,在集群分布下,如何保证这个znode是保证有序自增的,而不会出现并发情况下出现相同的临时node情况呢?
后经查阅,发现zookeeper有个非常重要的特性,就是在做写操作的时候,一个service上处理的请求,会经过所有zk下的service同意一致后才会返回成功,否则返回失败。这就是zookeeper的一致性,所有的更新必定是全局有序的
- Zk分布式锁和redis的区别
redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能
zk分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小
另外一点就是,如果是redis获取锁的那个客户端bug了或者挂了,那么只能等待超时时间之后才能释放锁;而zk的话,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁