小编hul*_*ier的帖子

关于动物园管理员锁定食谱的担忧

在阅读ZooKeeper的锁定配方时,我感到困惑.似乎这个分布式锁定的配方无法保证"任何两个客户端认为它们持有相同锁定的任何快照".但是由于ZooKeeper被如此广泛采用,如果参考文档中存在这样的错误,有人应该在很久以前就指出它,那么我误解了什么呢?

引用分布式锁的配方:

完全分布式锁,全局同步,意味着在任何快照时,没有两个客户端认为它们拥有相同的锁.这些可以使用ZooKeeeper实现.与优先级队列一样,首先定义一个锁定节点.

  1. 使用路径名" locknode/guid-lock-" 调用create(),并设置序列和短暂标志.
  2. 在锁定节点上调用getChildren()而不设置监视标志(这对于避免群体效应很重要).
  3. 如果在步骤1中创建的路径名具有最低序列号后缀,则客户端具有锁,并且客户端退出协议.
  4. 客户端调用exists(),并在lock目录中的路径上设置watch标志,并使用下一个最低序列号.
  5. 如果exists()返回false,则转到步骤2.否则,在转到步骤2之前,等待上一步中路径名的通知.

考虑以下情况:

  • Client1成功获取了锁(在步骤3中),使用ZooKeeper节点"locknode/guid-lock-0";
  • Client2创建了节点"locknode/guid-lock-1",无法获取锁,现在正在观看"locknode/guid-lock-0";
  • 后来,由于某种原因(比如网络拥塞),Client1无法按时向ZooKeeper集群发送心跳消息,但Client1仍在工作,错误地假设它仍然保持锁定.
  • 但是,ZooKeeper可能会认为Client1的会话超时了

    1. 删除"locknode/guid-lock-0",
    2. 向Client2发送通知(或者先发送通知?),
    3. 但无法及时向Client1发送"会话超时"通知(例如,由于网络拥塞).
  • Client2获取通知,转到步骤2,获取它自己创建的唯一节点""locknode/guid-lock-1";因此,Client2假定它持有锁.
  • 但与此同时,Client1认为它持有锁.

这是一个有效的场景吗?

apache-zookeeper

19
推荐指数
1
解决办法
7377
查看次数

标签 统计

apache-zookeeper ×1