ZooKeeper API使用之实现分布式锁


分布式锁的设计

使用Zookeeper API 来实现一个分布式锁时,应该怎样设计呢?

zookeeper 分布式锁源代码:https://github.com/apache/zookeeper/tree/branch-3.5.5/zookeeper-recipes/zookeeper-recipes-lock

使用临时顺序 znode (比如: /lock)来表示获取锁的请求,创建最小后缀数字 znode 的用户成功拿到锁。

如上图所示,有3个锁请求,分别是后续数字1,后续数字2,后续数字3。因为数字1 是最小的,所以后续数字1的请求能够拿到锁,成为锁的持有者。

避免羊群效应(herd effect)

在设计锁时要注意避免羊群效应。

把锁请求者按照后缀数字进行排队,后缀数字小的锁请求者先获取锁。如果所有的锁请求者都 watch 锁持有者,当代表锁请求者的 znode 被删除以后,所有的锁请求者都会通知到,但是只有一个锁请求者能拿到锁。这就是羊群效应。

为了避免羊群效应,每个锁请求者 watch 它前面的锁请求者。每次锁被释放,只会有一个锁请求者会被通知到。这样做还让锁的分配具有公平性,锁定的分配遵循先到先得的原则。

如上图所示,后续数字3的锁请求它 watch 的不是锁持有者(后续数字1的锁请求者),而是 watch 它前面的锁请求者(后续数字2)

代码展示

运行测试用例

运行 zookeeper-recipes-queue 中的单元测试文件 DistributedQueueTest:

cd zookeeper/zookeeper-recipes/zookeeper-recipes-lock

mvn test -Dtest=org.apache.zookeeper.recipes.lock.WriteLockTest

参考


文章作者: 张权
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张权 !
评论
  目录