这几种常见的“分布式锁”写法,搞懂再也不怕面试官,安排( 三 )


这几种常见的“分布式锁”写法,搞懂再也不怕面试官,安排

文章插图
 
Zookeeper写法在介绍 zookeeper 实现分布式锁的机制之前,先粗略介绍一下 zk 是什么东西: zk 是一种提供配置管理、分布式协同以及命名的中心化服务 。它的模型是这样的:包含一系列的节点,叫做znode,就好像文件系统一样每个 znode 表示一个目录,然后 znode 有一些特性,我们可以把它们分为四类:
  • 持久化节点(zk断开节点还在)
  • 持久化顺序节点(如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推)
  • 临时节点(客户端断开后节点就删除了)
  • 临时顺序节点
zookeeper分布式锁恰恰应用了临时顺序节点,下面我们就用图解的方式来看下是怎么实现的 。
获取锁首先,在 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…
它的使用方式也很简单,如下所示:
这几种常见的“分布式锁”写法,搞懂再也不怕面试官,安排

文章插图


推荐阅读