Concurrency 关于监视的通知的可用性

Concurrency 关于监视的通知的可用性,concurrency,apache-zookeeper,Concurrency,Apache Zookeeper,问题: 如果客户端A正在监视znode/A并尝试读取/b;客户端B在更新前删除/a/B。如果客户端A收到/A已消失的通知,它将停止读取/b 是否有可能按顺序发生以下情况 客户端A读取/A并设置手表 客户端A/A存在 客户端B/a 客户端B收到/a已消失的响应 客户端A读取/b 客户端A获取过时的信息 客户A收到通知/A已离开,但为时已晚 我假设有一个3.5客户端B更新/B,我也不认为是4。这是相关的 动物园管理员保证: 手表的订购与其他活动、其他手表和 异步回复。ZooKeeper客户端库确保

问题:

如果客户端A正在监视znode/A并尝试读取/b;客户端B在更新前删除/a/B。如果客户端A收到/A已消失的通知,它将停止读取/b

是否有可能按顺序发生以下情况

  • 客户端A读取/A并设置手表
  • 客户端A/A存在
  • 客户端B/a
  • 客户端B收到/a已消失的响应
  • 客户端A读取/b
  • 客户端A获取过时的信息
  • 客户A收到通知/A已离开,但为时已晚

  • 我假设有一个3.5客户端B更新/B,我也不认为是4。这是相关的

    动物园管理员保证:

    手表的订购与其他活动、其他手表和 异步回复。ZooKeeper客户端库确保 一切都井然有序

    如果您使用java,并且只使用异步方法,那么在zookeeper事件线程中,您将获得一个watchEvent,其中/a在异步读取/b之前被删除

    不过,如果使用同步zookeeper api,会有一个复杂的问题,因为这样会在代码中引入更多线程,这可能会违反顺序保证。请参阅java绑定中的注释,特别是这一部分

    同步调用可能不会以正确的顺序返回。例如 假设客户机执行以下处理:发出异步 在watch设置为true时读取节点/a,然后在完成 对读取的回调它对/a进行同步读取。)也许不太好 实践,但也不违法,这是一个简单的例子。) 请注意,如果异步读取和 同步读取时,客户端库将接收监视事件 saying/a在同步读取响应之前已更改,但是 由于完成回调正在阻塞事件队列,因此 同步读取将在手表之前返回新值/a 事件被处理


    因此,如果您使用的是同步api,A可能会在读取/b之后看到/A的监视事件。

    在zookeeper中,仅写入而不读取。 由于使用异步API时发生了该事件,因此在步骤5中,当某个客户端收到成功删除的响应后,客户端可能会读取过时的值

    这是因为您的读取请求可能到达Zookeeper节点,该节点认为它仍然是主节点,并且该节点在响应读取请求之前不会尝试与其他复制副本对话,因此它不会发现自己不再是主节点

    如果希望读取返回最新的值,可以通过在执行读取之前始终调用Sync()来强制线性化


    这将保证在调用Sync()之前,您的读取将看到在挂钟时间内发生的所有写入操作的效果。

    Hmm不确定我是如何错过此响应的。这对我来说有点复杂,但我想我明白了。