Zookeeper实现分布式锁

来源:互联网 发布:国债逆回购 知乎 编辑:程序博客网 时间:2024/06/05 19:11

在zookeeper中,通过数据节点来表示一个锁,例如/exclusive_lock/lock节点就可以被定义为一个锁。

1、排它锁

获取锁

所有的客户端都试图通过调用create()接口,在/exclusive_lock节点下创建临时子结点/exclusive_lock/lock。成功创建的客户端就认为获取了锁,其它没有获取到锁的客户端就需要到/exclusive_lock节点上注册一个子节点变更的Watcher监听,以便实时监听到lock节点的变更情况。

释放锁

释放锁分两种情况
  1. 获取到锁的客户端发生宕机,那么zookeeper上的这个临时节点就会被移除。
  2. 正常执行完业务逻辑后,客户端就会主动将自己创建的临时节点删除
当lock节点被移除时,zookeeper会通知所有在/exclusive_lock节点上注册了子节点变更Watcher监听的客户端。当其它客户端接收到通知后,再次重新发起分布式锁获取,即重复“获取锁”(创建lock临时子节点)过程。

排他锁流程图


2、共享锁

获取共享锁

获取共享锁时,所有客户端都会到/shared_lock这个节点下面创建一个临时顺序节点(格式如:"/shared_lock/[Hostname]-请求类型-序号"),例如读请求——/shared_lock/192.168.0.1-R-0000000001, 写请求——/shared_lock/192.168.0.1-W-0000000001。
步骤1、客户端调用create()方法创建一个类似于"/shared_lock/[Hostname]-请求类型-序号"的临时顺序节点。
步骤2、客户端调用getChildren()接口来获取所有已经创建的子节点列表,注意,这里不注册任何Watcher。
步骤3、如果无法获取共享锁,那么就调用exist()来对比自己小的那个节点注册Watcher。注意,这里“比自己小的节点”具体情况如下:
  1. 读请求:向比自己序号小的最后一个写请求节点注册Watcher监听。
  2. 写请求:向比自己序号小的最后一个节点注册Watcher监听。
步骤4、等待Watcher通知,继续进入步骤2。

释放锁

释放锁的逻辑和排他锁是一致的。

共享锁的流程图


原创粉丝点击