Zookeeper实现分布式锁

首先要介绍下ZK节点和监听机制

1.节点类型
持久节点(PERSISTENT)
持久节点是zookeeper中最常见的一种节点类型。所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点。
持久顺序节点(PERSISTENT_SEQUENTIAL)
持久顺序节点的基本特性和持久节点是一致的,额外的特性表现在顺序性上。在zookeeper中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,zookeeper会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。
临时节点(EPHEMERAL)
和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非连接断开。zookeeper规定在临时节点下面不能创建子节点。
临时顺序节点(EPHEMERAL_SEQUENTIAL)
临时顺序节点的基本特性和临时节点也是一致的,同样是在临时节点的基础上,添加了顺序性

2.监听机制
监听是 Zookeeper 中非常重要的特性,我们基于 zookeeper 上创建的节点,可以对这些节点绑定监听事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以基于 zookeeper 实现分布式锁、集群管理等功能

watcher 特性
当数据发生变化的时候, zookeeper 会产生一个 watcher 事件,并且会发送到客户端。但是客户端只会收到一次通知。如果后续这个节点再次发生变化,那么之前设置的 watcher 监听不会再起作用。(watcher 是一次性的)。
可以通过循环设置监听去达到永久监听的效果
总结起来watcher的特性有
1.一次性,无论是服务端还是客户端,一旦一个 Watcher 被触发,ZooKeeper 都会将其从相应的存储中移除。因此,在 Watcher 的使用上,需要反复注册。这样的设计有效地减轻了服务端的压力。
2.客户端watcher为串行执行,客户端 Watcher 回调的过程是一个串行同步的过程,这为我们保证了顺序,同时,需要注意的一点是,一定不能因为一个 Watcher 的处理逻辑影响了整个客户端的 Watcher 回调,所以,客户端 Watcher 类要尽量异步操作,这样不会影响后续回调。
3.轻量,WatcherEvent 是 ZooKeeper 整个 Watcher 通知机制的最小通知单元,这个数据结构中只包含三部分内容:通知状态、事件类型和节点路径。也就是说,Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容。具体内容需要客户端主动去获取。

下面描述使用zookeeper实现分布式锁的算法流程,

第一种实现(类公平锁的实现)

假设锁空间的根节点为/lock:
1.客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推。
2.客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,
如果是则认为获得锁,否则监听/lock的子节点变更事件,获得子节点变更通知后重复此步骤直至获得锁;
3.执行业务代码;
4.完成业务流程后,删除对应的子节点释放锁。

获取锁:判断自己创建的节点是够是最小的节点 / 监听删除消息

所以调整后的分布式锁算法流程如下:

1.客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推;
2.客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,
如果是则认为获得锁,否则监听在自己前面的一个子节点的删除事件,获得子节点变更通知后重复此步骤直至获得锁;
3.执行业务代码;
4.完成业务流程后,删除对应的子节点释放锁。

第二种实现(类非公平锁实现)

多个客户端,同时在zookeeper上创建相同的一个临时节点,
因为临时节点路径是保证唯一,只要谁能够创建节点成功,谁就能够获取到锁,
没有创建成功节点,就会进行等待,
当释放锁(删除节点)的时候,采用事件通知(watcher)唤醒客户端重新获取锁。

参考:
https://blog.csdn.net/hohoo1990/article/details/78617336
https://blog.csdn.net/yswKnight/article/details/82429617

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值