ZooKeeper客户端开发 C语言
http://www.cnblogs.com/caosiyang/archive/2012/11/09/2763190.html
http://www.cnblogs.com/caosiyang/archive/2012/11/09/2763190.html
关于ZooKeeper Watches
zookeeper所有读操作(getData(),getChildren(),exists())具有设置watch的选项。
zookeeper watch的定义如下:watch事件是一次性触发器,当watch监视的数据发生变化时,通知设置了该watch的client,即watcher。
需要注意三点:
1.一次性触发器
client在一个节点上设置watch,随后节点内容改变,client将获取事件。当节点内容再次改变,client不会获取这个事件,除非它又执行了一次读操作并设置watch
2.发送至client,watch事件延迟
watch事件异步发送至观察者。比如说client执行一次写操作,节点数据内容发生变化,操作返回后,而watch事件可能还在发往client的路上。这种情况下,zookeeper提供有序保证:client不会得知数据变化,直到它获取watch事件。网络延迟或其他因素可能导致不同client在不同时刻获取watch事件和操作返回值。
3.设置watch的数据内容
涉及到节点改变的不同方式。比方说zookeeper维护两个watch列表:节点的数据watch和子节点watch。getData()和exists()设置了内容watch,getChildren()设置了子节点watch,操作返回的数据类型不同,前者是节点的内容,后者是节点的子节点列表。setData()触发内容watch,create()触发当前节点的"内容watch"和其父节点的"子节点watch",delete()同时触发"内容watch"和"子节点watch"(其子节点被全部删除),以及其父节点的"子节点watch"。说白了,对当前节点的操作,要考虑到对其父节点与子节点的影响。
watch在客户端所连接的服务端本地维护。watch的设置、维护、分发操作都很轻量级。当客户端连接到新的服务端,watch将被任一会话事件触发。与服务端断开连接时,不能获取watch事件。客户端重连后,之前注册的watch将被重新注册并在需要时触发。通常这一切透明地发生,用户不会察觉到。有一种情况watch可能丢失:之前对一个尚未建立的节点的设置了exists watch,如果断开期间该节点被建立或删除,那么此watch将丢失。
对于watch,zookeeper提供以下保证:
1.watch对于其他事件、watch、异步响应是有序的。zookeeper client library保证有序分发
2.客户端监视一个节点,总是先获取watch事件,再发现节点的数据变化。
3.watch事件的顺序对应于zookeeper服务所见的数据更新的顺序。
关于watch要记住的是:
1.watch是一次性触发的,如果获取一个watch事件并希望得到新变化的通知,需要重新设置watch
2.watch是一次性触发的并且在获取watch事件和设置新watch事件之间有延迟,所以不能可靠的观察到节点的每一次变化。要认识到这一点。
3.watch object只触发一次,比如,一个watch object被注册到同一个节点的getData()和exists(),节点被删除,仅对应于exists()的watch ojbect被调用
4.若与服务端断开连接,直到重连后才能获取watch事件。
ZooKeeper访问控制
zookeeper使用ACL(Access Control List)控制对节点的访问。ACL与Unix文件访问权限类似,采用权限位的形式控制节点的可操作类型,zookeeper没有拥有者和用户组的概念,使用ACL指定每个用户的访问权限。一个ACL只用于一个节点,注意不能用于该节点的子节点,即每个节点的访问权限由其自身的ACL决定。
每一个客户端连接在zookeeper内部有唯一的id,zookeeper将连接和id关联起来,客户端试图访问节点时,用id与节点ACL进行比对,以确定客户端的访问权限。
ACL由键值对构成,格式是(scheme:expression, perms)。expression内容格式特定于scheme。
ACL权限
ZooKeeper客户端开发
关于C开发,zookeeper提供了两个库:zookeeper_st(单线程库)与zookeeper_mt(多线程库)。zookeeper_st放弃了事件循环,可在事件驱动的应用程序中使用。而zookeeper_mt更加易用,与Java API类似,创建一个网络IO线程和一个事件分发线程,用来维护连接和执行回调。
在具体使用上,zookeeper_st仅提供了异步API与回调,用以集成至应用程序的事件循环。它只是为了支持pthread库不可用或不稳定的平台而存在,例如FreeBSD 4.x。除此以外的其他情况,应使用提供同步与异步两种API的zookeeper_mt。
采用zookeeper_mt库的zookeeper客户端使用了3个线程:
线程1是业务逻辑层,负责与用户直接交互,主要是zookeeper库提供的API
线程2是网络IO层,负责与zookeeper服务端的网络通信,包括发送业务逻辑层的API调用生成的请求数据、服务端的响应数据、服务端的watch事件数据
线程3是事件处理层,负责执行watch回调
Watch事件类型:
ZOO_CREATED_EVENT:节点创建事件,需要watch一个不存在的节点,当节点被创建时触发,此watch通过zoo_exists()设置
ZOO_DELETED_EVENT:节点删除事件,此watch通过zoo_exists()或zoo_get()设置
ZOO_CHANGED_EVENT:节点数据改变事件,此watch通过zoo_exists()或zoo_get()设置
ZOO_CHILD_EVENT:子节点列表改变事件,此watch通过zoo_get_children()或zoo_get_children2()设置
ZOO_SESSION_EVENT:会话失效事件,客户端与服务端断开或重连时触发
ZOO_NOTWATCHING_EVENT:watch移除事件,服务端出于某些原因不再为客户端watch节点时触发
watch事件与zookeeper读操作的对应关系图:
更多推荐
所有评论(0)