zookeeper watch机制的理解

首先我们看看为什么添加Watch。

ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能。

多个分布式进程通过ZooKeeper提供的 API来操作共享的ZooKeeper内存数据对象ZNode来达成某种一致的行为或结果,这种模式本质上是基于状态共享的并发模型,与Java的多线程并发模型一致,他们的线程或进程都是“共享式内存通信”。Java没有直接提供某种响应式通知接口来监控某个对象状态的变化,只能要么浪费CPU时间毫无响应式的轮询重试,或基于Java提供的某种主动通知(Notif)机制(内置队列)来响应状态变化,但这种机制是需要循环阻塞调用。而ZooKeeper实现这些分布式进程的状态(ZNode的Data、Children)共享时,基于性能的考虑采用了类似的异步非阻塞的主动通知模式即Watch机制,使得分布式进程之间的“共享状态通信”更加实时高效,其实这也是ZooKeeper的主要任务决定的—协调。

所有的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事件;从ZooKeeper接收到的watch事件顺序一定和ZooKeeper服务所看到的事件顺序是一致的。

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

Watch是一次性触发器,如果你得到了一个watch事件,而你希望在以后发生变更时继续得到通知,你应该再设置一个watch。
因为watch是一次性触发器,而获得事件再发送一个新的设置watch的请求这一过程会有延时,所以你无法确保你看到了所有发生在ZooKeeper上的一个节点上的事件。所以请处理好在这个时间窗口中可能会发生多次znode变更的这种情况。(你可以不处理,但至少请认识到这一点)。

一个watch对象或一个函数/上下文对,为一个事件只会被通知一次。比如,如果同一个watch对象在同一个文件上分别通过exists和getData注册了两次,而这个文件之后被删除了,这时这个watch对象将只会收到一次该文件的deletion通知。

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

总结

以上就是本文关于zookeeper watch机制的全部介绍,有兴趣的朋友可以参阅:为zookeeper配置相应的acl权限、apache zookeeper使用方法实例详解等,希望对大家有所帮助。

(0)

相关推荐

  • 理解zookeeper选举机制

    zookeeper集群 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点和redis是相同的,即对客户端来讲每个服务器都是平等的. 这篇主要分析leader的选择机制,zookeeper提供了三种方式: LeaderElection AuthFastLeaderElection FastLeaderElection 默认的算法是FastLeaderElection,所以这篇主要分析它的选举机制. 选择机制中的概

  • 浅谈Zookeeper开源客户端框架Curator

    zookeepercurator Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情, 于是在它的基础上包装了一下, 提供了一套更好用的客户端框架. Netflix在用ZooKeeper的过程中遇到的问题, 我们也遇到了, 所以开始研究一下, 首先从他在github上的源码, wiki文档以及Netflix的技术blog入手. 看完官方的文档之后,

  • apache zookeeper使用方法实例详解

    本文涉及了Apache Zookeeper使用方法实例详解的相关知识,接下来我们就看看具体内容. 简介 Apache Zookeeper 是由 Apache Hadoop 的 Zookeeper 子项目发展而来,现在已经成为了 Apache 的顶级项目.Zookeeper 为分布式系统提供了高效可靠且易于使用的协同服务,它可以为分布式应用提供相当多的服务,诸如统一命名服务,配置管理,状态同步和组服务等. Zookeeper 接口简单,开发人员不必过多地纠结在分布式系统编程难于处理的同步和一致性问

  • Shell脚本实现自动安装zookeeper

    A:本脚本运行的机器,Linux RHEL6 B,C,D,...:待安装zookeeper cluster的机器, Linux RHEL6 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装zk的机器B,C,D,...上,然后就可以在A上运行本脚本: 复制代码 代码如下: $ ./install_zookeeper 前提: B, C, D机器必须配置好repo,本脚本使用的是cdh5的repo, 下面的内容保存到:/etc/yum.repos.d/cloudera-cdh5.repo: 复

  • zookeeper watch机制的理解

    首先我们看看为什么添加Watch. ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能. 多个分布式进程通过ZooKeeper提供的 API来操作共享的ZooKeeper内存数据对象ZNode来达成某种一致的行为或结果,这种模式本质上是基于状态共享的并发模型,与Java的多线程并发模型一致,他们的线程或进程都是"共享式内存通信".Java没有直接提供某种响应式通知接口来监控某个对象状态的变化,只能要么浪费C

  • php中ob函数缓冲机制深入理解

    下面就php中ob函数缓冲机制通过文字说明加代码分析的形式给大家展示如下: 对于一个刚刚入门的php程序员来说,php缓冲区是几乎透明的.在他们心目中,一个echo print_r 函数,数据便会'嗖'的一声飞到浏览器上,显示出来.我也一直如此单纯地认为. 其实,在技术的世界里,向来都是由简单到复杂,也许那些技术开发者开始单纯如你我,但是面对残酷的现实,不得不调整策略,以期提高机器运行效率,最后想到了那些让我们赞叹的idea. 说到缓冲,也就是buffer,这里必须要和缓存做一下比较,单纯地比较

  • Java反射机制深入理解

    Java反射机制深入理解 一.概念 反射就是把Java的各种成分映射成相应的Java类. Class类的构造方法是private,由JVM创建. 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作.例如它允许一个java的类获取他所有的成员变量和方法并且显示出来.Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性.例如,Pascal.C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息.

  • 对于js垃圾回收机制的理解

    原理 找到不再被使用的变量,然后释放其占用的内存,但这个过程不是时时的,因为其开销比较大, 所以垃圾回收器会按照固定时间间隔周期性的执行 回收方式 a.标记清除 当变量进入环境时,将这个变量标记为"进入环境";当变量离开环境时,则将其标记为"离开环境". 标记"离开环境"的就回收内存 b.引入计数(低级浏览器) 当变量声明,第一次赋值时记为1,然后当这个变量值改变时,记录为0,将计数为0的回收 内存泄露 a.意外的全局变量引起的内存泄露 原因:

  • Java异常处理机制深入理解

    目录 1.初识异常 2.异常的基本用法 异常处理流程 3.为什么要使用异常? 异常应只用于异常的情况 4. 异常的种类 4.1 受查异常 解决方案: 4.2非受查异常 5.如何使用异常 避免不必要的使用受查异常 6.自定义异常 1.初识异常 我们在写代码的时候都或多或少碰到了大大小小的异常,例如: public class Test { public static void main(String[] args) { int[] arr = {1,2,3}; System.out.println

  • 谈一谈JS消息机制和事件机制的理解

    消息/事件机制是几乎所有开发语言都有的机制,并不是deviceone的独创,在某些语言称之为消息(Event),有些地方称之为(Message). 其实原理是类似的,只不过有些实现的方式要复杂一点.我们deviceone统一就叫消息. 消息基础概念 还有一些初学者不太熟悉这个机制,我们先简单介绍一些基础概念,如果熟悉的人可以跳过这个部分. 一个/条消息可以理解为是一个数据结构,包含以下几个基本部分: 1.消息源:就是消息的来源,发出这个消息的对象 2.消息名:就是消息的唯一标示 3.消息数据:消

  • C++多态的实现机制深入理解

    在面试过程中C++的多态实现机制经常会被面试官问道.大家清楚多态到底该如何实现吗?下面小编抽空给大家介绍下多态的实现机制. 1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 2. 存在虚函数的类都有一个一维的虚函数表叫做虚表.类的对象有一个指向虚表开始的虚指针.虚表是和类对应的,虚表指针是和对象对应的. 3. 多态性是一个接口多种实现,是面向对象的核心.分为类的多态性和函数的多态性. 4. 多态用虚函数来实现,结合动态绑定. 5. 纯虚函数是虚函数再加上= 0. 6.

  • Android 渲染机制深入理解

    基础知识 CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps.Drawables等都是一起打包到统一的纹理). GPU:一个类似于CPU的专门用来处理Graphics的处理器, 作用用来帮助加快格栅化操作,当然,也有相应的缓存数据(例如缓存已经光栅化过的bitmap等)机制. OpenGL ES:是手持嵌入式设备的3DAPI,跨平台的.功能完善的2D和3D图形应用程序接口API,有一套固定渲染管线流程. OpenGL ES详解 D

  • Javascript 垃圾收集机制介绍理解

    经常使用 Javascript 的人会琢磨其垃圾收集机制,Javascript 并不像 C,C++ 那样需要开发者手动去清除垃圾,在编写 Javascript 程序是,开发者无需关心内存使用问题,所需内存分配以及无用内存(垃圾)的回收完全实现了自动管理.究其根源,主要是程序收集那些不再使用的变量,并且释放其占用的内存.因此,垃圾收集机制会按照固定时间间隔,周期性反复的执行这一操作. 举例来说,局部变量只存在于函数内部,程序会为局部变量在栈内存或堆内存中分配对应的存储空间,当函数运行结束,局部变量

随机推荐