今天在统计页面上发现有个节点丢失了,经过仔细分析后,发现同一个节点上的二个应用(同时监控zk)其中一个丢失了一个event,检查zk cluster没有发现异常。。。

通过网络搜寻,出现miss event的情况说的都是监听前已经有node,删除后才register,所以这属于正常现象。

排除网络问题,因为我相信zk在notified event时如果不通是有异常提示的。

  1. cat /path/to/log/file | grep NodeChildrenChanged
  2. 2013-05-31 02:30:23,120 [main-EventThread] (ZookeeperMonitor.java:158) WARN  xxx.ZookeeperMonitor - NodeChildrenChanged,reloading data with event:WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/node/svr
  3. 2013-05-31 02:30:23,906 [main-EventThread] (ZookeeperMonitor.java:158) WARN  xxx.ZookeeperMonitor - NodeChildrenChanged,reloading data with event:WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/node/svr
  4. 2013-05-31 02:30:50,179 [main-EventThread] (ZookeeperMonitor.java:158) WARN  xxx.ZookeeperMonitor - NodeChildrenChanged,reloading data with event:WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/node/svr
  5. 比较其它正常应用,最后一个缺少了event。

迫于无耐还是硬着头皮再找了下,发现了答案如下:

------------
-------------

所 有的Zookeeper读操作,包括getData()、getChildren()和exists(),都有一个开关,可以在操作的同时再设置一个 watch。在ZooKeeper中,Watch是一个一次性触发器,会在被设置watch的数据发生变化的时候,发送给设置watch的客户端。 watch的定义中有三个关键点:

  • 一次性触发器

    一 个watch事件将会在数据发生变更时发送给客户端。例如,如果客户端执行操作getData(“/znode1″, true),而后 /znode1 发生变更或是删除了,客户端都会得到一个  /znode1 的watch事件。如果  /znode1 再次发生变更,则在客户端没有设置新的watch的情况下,是不会再给这个客户端发送watch事件的。

  • 发送给客户端

    这 就是说,一个事件会发送向客户端,但可能在在操作成功的返回值到达发起变动的客户端之前,这个事件还没有送达watch的客户端。Watch是异步发送 的。但ZooKeeper保证了一个顺序:一个客户端在收到watch事件之前,一定不会看到它设置过watch的值的变动。网络时延和其他因素可能会导 致不同的客户端看到watch和更新返回值的时间不同。但关键点是,每个客户端所看到的每件事都是有顺序的。

  • 被设置了watch的数据

    这 是指节点发生变动的不同方式。你可以认为ZooKeeper维护了两个watch列表:data watch和child watch。getData()和exists()设置data watch,而getChildren()设置child watch。或者,可以认为watch是根据返回值设置的。getData()和exists()返回节点本身的信息,而getChildren()返回 子节点的列表。因此,setData()会触发znode上设置的data watch(如果set成功的话)。一个成功的 create() 操作会触发被创建的znode上的数据watch,以及其父节点上的child watch。而一个成功的 delete()操作将会同时触发一个znode的data watch和child watch(因为这样就没有子节点了),同时也会触发其父节点的child watch。

Watch 由client连接上的ZooKeeper服务器在本地维护。这样可以减小设置、维护和分发watch的开销。当一个客户端连接到一个新的服务器上 时,watch将会被以任意会话事件触发。当与一个服务器失去连接的时候,是无法接收到watch的。而当client重新连接时,如果需要的话,所有先 前注册过的watch,都会被重新注册。通常这是完全透明的。只有在一个特殊情况下,watch可能会丢失:对于一个未创建的znode的exist watch,如果在客户端断开连接期间被创建了,并且随后在客户端连接上之前又删除了,这种情况下,这个watch事件可能会被丢失。

ZooKeeper对Watch提供了什么保障

对于watch,ZooKeeper提供了这些保障:

  • Watch与其他事件、其他watch以及异步回复都是有序的。 ZooKeeper客户端库保证所有事件都会按顺序分发。

  • 客户端会保障它在看到相应的znode的新数据之前接收到watch事件。//这保证了在process()再次利用zk client访问时数据是存在的

  • 从ZooKeeper接收到的watch事件顺序一定和ZooKeeper服务所看到的事件顺序是一致的。

关于Watch的一些值得注意的事情

  • Watch是一次性触发器,如果你得到了一个watch事件,而你希望在以后发生变更时继续得到通知,你应该再设置一个watch。

  • 因 为watch是一次性触发器,而获得事件再发送一个新的设置watch的请求这一过程会有延时,所以你无法确保你看到了所有发生在ZooKeeper上的 一个节点上的事件。所以请处理好在这个时间窗口中可能会发生多次znode变更的这种情况。(你可以不处理,但至少请认识到这一点)。//也就是说,在process()中如果处理得慢而没有注册new watch时,在这期间有其它事件出现时是不会通知!!之前可能就是没有意识到这点所以才引出本话题***********

  • 一个watch对象或一个函数/上下文对,为一个事件只会被通知一次。比如,如果同一个watch对象在同一个文件上分别通过exists和getData注册了两次,而这个文件之后被删除了,这时这个watch对象将只会收到一次该文件的deletion通知。//同一个watch注册同一个节点多次只会生成一个event.这里我想到如果一个watch注册不同的node,也应当出现多个event?

  • 当你从一个服务器上断开时(比如服务器出故障了),在再次连接上之前,你将无法获得任何watch。请使用这些会话事件来进入安全模式:在disconnected状态下你将不会收到事件,所以你的程序在此期间应该谨慎行事。

zookeeper 丢失事件/miss event的更多相关文章

  1. SQL Server扩展事件的使用ring_buffer target时“丢失”事件的原因分析以及ring_buffer target潜在的问题

    事情起因: 排查SQL Server上的死锁问题,一开始想到的就是扩展事件, 第一种方案,开profile守株待兔吧,显得太low了,至于profile的变种trace吧,垂垂老矣,也一直没怎么用过. ...

  2. [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event

    [DOM Event Learning] Section 2 概念梳理 什么是事件 DOM Event   事件 事件(Event)是用来通知代码,一些有趣的事情发生了. 每一个Event都会被一个E ...

  3. 事件(event),正则

    1.事件(event):事件是可以被 JavaScript 侦测到的行为.网页中的每个元素都可以产生某些可以触发 JavaScript 函数的事件.2.事件源: 触发事件的元素 事件: 被 JavaS ...

  4. 添加事件及Event对象的兼容写法

    一.事件流 事件流描述的是从页面中接受事件的顺序. IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流 1.事件冒泡 事件冒泡,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点) ...

  5. Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析

    这一章,我们来分析Cocos2d-x 事件机制相关的源码, 根据Cocos2d-x的工程目录,我们可以找到所有关于事件的源码都存在放在下图所示的目录中. 从这个event_dispatcher目录中的 ...

  6. Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法

    Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法 最近在适用Ext JS4开发 ...

  7. 重新审视事件对象event

    前言:之前在学习事件对象event时,一是一直在chrome浏览器(作为主运行环境)下运行调试自个儿程序,二是可能当时对事件对象理解不透彻才导致现在对事件对象的用法陷入了一个大坑,遂以此篇博客记之. ...

  8. C#事件(Event)学习日记

    event 关键字的来由,为了简化自定义方法的构建来为委托调用列表增加和删除方法. 在编译器处理 event 关键字的时候,它会自动提供注册和注销方法以及任何必要的委托类型成员变量. 这些委托成员变量 ...

  9. 简单总结焦点事件、Event事件对象、冒泡事件

    每学习一些新的东西,要学会复习,总结和记录. 今天来简单总结一下学到的几个事件:焦点事件.Event事件对象.冒泡事件 其实这几个事件应该往深的说是挺难的,但今天主要是以一个小菜的角度去尝试理解一些基 ...

随机推荐

  1. [Immutable.js] Converting Immutable.js Structures to Javascript and other Immutable Types

    Immutable.js provides several conversion methods to migrate one structure to another. Each Immutable ...

  2. Java内存区域和GC机制篇

    Java内存区域和GC机制一.目录 1.Java垃圾回收概括 2.Java内存区域 3.Java对象的访问方式 4.Java内存访问机制 5.Java GC 机制 6.Java垃圾收集器 二.Java ...

  3. Android Eclipse Errors

    1.The import org.apache.http.client; tip: cannot be resolved; resolve: Find library in your sdk and ...

  4. Linq to Entities中无法构造实体或复杂类型

    EF中在使用linq就行查询select时不能直接使用自动映射生成的类,需要在单独声明一个类或者使用匿名类在查询完成后再转为对应的对象. public partial class WebForm1 : ...

  5. ios开发 AFNetworking的基本使用方法

    AFNetworking的基本使用方法 什么是GET请求? 如果只是单纯的下载数据, 使用GET请求 什么是POST请求? 特点:  请求的内容不会出现在URL网址中 向服务器发送用户名和密码, 或者 ...

  6. c#窗体的传值方法

    了解了窗体的显示相关知识,接着总结一下窗体的传值方法:  .通过构造函数  特点:传值是单向的(不可以互相传值),实现简单 实现代码如下: 在窗体Form2中         int value1;  ...

  7. yii2 打印sql语句

    echo $temp_chat_query->createCommand()->getRawSql();

  8. ETL概述

    转自:http://blog.csdn.net/leosoft/article/details/4279536 ETL,Extraction-Transformation-Loading的缩写,中文名 ...

  9. 淘管 ERP项目与淘宝对接中产生的若干问题及处理办法

    现象:ERP绑定淘宝后,下载商品数据时如果成功,ajax不断尝试重发. 原因:  /app/taoapi/lib/top/TopClient.php 中的curl()方法成功后,返回空值,而前端收到空 ...

  10. python笔记之ZipFile模块

    python笔记之ZipFile模块 zipfile模块用来做zip格式编码的压缩和解压缩的,zipfile里有两个非常重要的class, 分别是ZipFile和ZipInfo, 在绝大多数的情况下, ...