问题:
如果客户端A正在监视znode /a并试图读取/b;而客户端B在更新/b之前删除/a。如果客户端A收到/a已消失的通知,它将停止读取/b。
是否有可能按顺序发生以下情况?
发布于 2014-03-02 22:31:16
我想有一个3.5ClientB更新的/b,我也不认为4。是相关的。
动物园管理员保证是这里,
监视是针对其他事件、其他监视和异步响应排序的。ZooKeeper客户端库确保按顺序分派所有东西。
如果您使用java,并且只使用异步方法,那么在zookeeper线程中,您将得到一个watchEvent,该/a在异步读取/b之前被删除。
但是,如果您使用同步的zookeeper,则会有一个复杂的问题,因为您在代码中引入了更多的线程,这可能违反排序保证。请参阅java绑定这里中的注释,特别是本部分,
同步调用可能不会以正确的顺序返回。例如,假设客户端执行以下处理:发出节点/a的异步读取,并将手表设置为true,然后在read的完成回调中对/a执行同步读取(可能不是很好的实践,但也不是非法的,这是一个简单的示例)。注意,如果异步读取和同步读取之间的/a发生了更改,客户端库将接收到在同步读取响应之前更改了/a的监视事件,但是由于完成回调阻塞了事件队列,所以在处理监视事件之前,同步读取将与/a的新值一起返回。
因此,如果您使用的是同步api,那么在读取/a之后,可能会看到/b的监视事件。
发布于 2018-10-05 18:14:48
在动物园管理员中,只写服从线性化,不读。由于在使用异步API时发生了该事件,因此在步骤5中,客户端可以在某个客户端得到A被成功删除的响应后读取陈旧值A。
这是因为您的读取请求可能到达自认为仍然是主节点的节点,并且在响应读取请求之前,该节点将不会尝试与其他副本对话,因此不会发现它不再是主程序。
如果希望read返回最新值,则可以在读取之前始终调用Sync()强制线性化。
这将保证在调用Sync()之前,您的读取将看到在挂钟时间发生的所有写入的效果。
https://stackoverflow.com/questions/22029453
复制相似问题