ZK Exists Watch 和 Disconnect event

ZK Exists Watch 和 Disconnect event

本篇博客信息主要参考书籍, zookeeper ,记录的主要是书中涉及到的一个zookeeper的特殊实例,博主也在工作中遇到了这个问题,特此翻译记录

正常情况下,当一个client 连接到zookeeper 的ensember(假设包含节点server1,server2,server3)后,假设一开始client连接了节点server1,并且设置了若干watch,再之后连接断开,但是client 在session timeout之后成功连接到了server2. 这时候,先前设置在各个节点上的watcher会被重新记录,如果断开期间有触发watcher,会在成功连接到server2 之后再次触发。

但是有个cornor case。就是,如果我们的client watch了一个exist 事件,用于检测这个节点什么时候被成功创建,

如果client在断开期间,有另外一个clientB 先创建了这个节点,然后又在client重新连接到server2 之前,又一次删除了这个节点。这种情况下,client的exist watch 就会完全无感知。

(反过来,如果client watch了一个exist 事件,用于检测某个已存在节点时候被删除是没有问题的。)

原理如下:

为了更加无缝的处理zookeper连接断开的问题,zookeeper的client sdk会在断开重连后,同时把已有的watches设置到新的zookeeper 节点上。主要就是因为zookeeper sdk会把watches和最近的zxid一并发布到

新的zookeeper server节点上。这时候,新连接的zookeeper节点会在建立连接的时候会把最新的timestamp和client传上来的last zxid进行对比,如果发现这些被watch的znodes存在有修改,并且修改介于last zxid和server latest 修改 timestamp,就会触发这些watch

这个逻辑对于非exists的watch工作的非常完美。但是exists操作的特异之处就是当它用于检测节点从无到有的情况下,由于断开期间,此被watch节点有可能先建立,马上又删除,节点不存在的情况下,zookeeper也就无法利用zxid进行watcher的补足,导致watcher漏触发。这种情况下, zookeeper只能保证重新连接新服务器后,将这个watch注册上去,期间的触发就会被丢失了。

由于这个conner case 很容易被忽略,建议少使用exists watch 来检测节点的建立事件。如果一定要用,也建议这个被检测的节点在建立后不会被删除。防止出现这种conner case。

《ZK Exists Watch 和 Disconnect event》 existwatch_and_disconnect.png

    原文作者:来福马斯特
    原文地址: https://www.jianshu.com/p/942309884600
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞