文章插图
Zookeeper写法在介绍 zookeeper 实现分布式锁的机制之前,先粗略介绍一下 zk 是什么东西: zk 是一种提供配置管理、分布式协同以及命名的中心化服务 。它的模型是这样的:包含一系列的节点,叫做znode,就好像文件系统一样每个 znode 表示一个目录,然后 znode 有一些特性,我们可以把它们分为四类:
- 持久化节点(zk断开节点还在)
- 持久化顺序节点(如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推)
- 临时节点(客户端断开后节点就删除了)
- 临时顺序节点
获取锁首先,在 Zookeeper 当中创建一个持久节点 ParentLock 。当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序节点 Lock1 。
文章插图
之后,Client1 查找 ParentLock 下面所有的临时顺序节点并排序,判断自己所创建的节点 Lock1 是不是顺序最靠前的一个 。如果是第一个节点,则成功获得锁 。
文章插图
这时候,如果再有一个客户端 Client2 前来获取锁,则在 ParentLock 下再创建一个临时顺序节点Lock2 。
文章插图
Client2 查找 ParentLock 下面所有的临时顺序节点并排序,判断自己所创建的节点 Lock2 是不是顺序最靠前的一个,结果发现节点 Lock2 并不是最小的 。
于是,Client2 向排序仅比它靠前的节点 Lock1 注册 Watcher,用于监听 Lock1 节点是否存在 。这意味着 Client2 抢锁失败,进入了等待状态 。
文章插图
这时候,如果又有一个客户端 Client3 前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock3 。
文章插图
Client3 查找 ParentLock 下面所有的临时顺序节点并排序,判断自己所创建的节点 Lock3 是不是顺序最靠前的一个,结果同样发现节点 Lock3 并不是最小的 。
于是,Client3 向排序仅比它靠前的节点 Lock2 注册 Watcher,用于监听 Lock2 节点是否存在 。这意味着 Client3 同样抢锁失败,进入了等待状态 。
文章插图
这样一来,Client1 得到了锁,Client2 监听了 Lock1,Client3 监听了 Lock2 。这恰恰形成了一个等待队列,很像是 Java 当中 ReentrantLock 所依赖的 AQS(AbstractQueuedSynchronizer) 。
释放锁释放锁分为两种情况:
1.任务完成,客户端显示释放
当任务完成时,Client1 会显示调用删除节点 Lock1 的指令 。
文章插图
2.任务执行过程中,客户端崩溃
获得锁的 Client1 在任务执行过程中,如果 Duang 的一声崩溃,则会断开与 Zookeeper 服务端的链接 。根据临时节点的特性,相关联的节点 Lock1 会随之自动删除 。
文章插图
由于 Client2 一直监听着 Lock1 的存在状态,当 Lock1 节点被删除,Client2 会立刻收到通知 。这时候 Client2 会再次查询 ParentLock 下面的所有节点,确认自己创建的节点 Lock2 是不是目前最小的节点 。如果是最小,则 Client2 顺理成章获得了锁 。
文章插图
同理,如果 Client2 也因为任务完成或者节点崩溃而删除了节点 Lock2,那么 Client3 就会接到通知 。
文章插图
最终,Client3 成功得到了锁 。
文章插图
Curator在 Apache 的开源框架 Apache Curator 中,包含了对 Zookeeper 分布式锁的实现 。github.com/apache/cura…
它的使用方式也很简单,如下所示:
文章插图
推荐阅读
- 电脑的辐射
- 怎么消除紧张
- 常见的花茶价格介绍,勿忘我花茶的价格勿忘我花茶的泡法
- 女人不管出门多赶,尽量化淡妆!记住这3个窍门,简单易学显气色
- 不要随意触摸车内这四个按钮,否则会有车辆损坏和人员死亡的危险
- 常见草莓的区别和吃法
- 为什么语音里自己的声音能这么难听?
- 家常炒拉面有技巧,这样做比面馆都好吃还不油腻,食材多,真营养
- 修水龙头是什么梗?
- 年底想体检,却不知道查什么?这份千元以下的体检清单请收好