ZooKeeper编程指南(三)
监控
zk中所有的读操作-getData(),getChildren(),exists() - 都有设置监控的参数。这就是zk对监控的定义:监控事件是一次性的,被发送给设置监控的客户端,监控的数据发生改变时监控事件发生。在监控的定义中有三个关键点:
1、一次性触发 数据改变时,监控事件被发送给客户端。例如,如果客户端执行操作getData("/znode1", ture),之后节点/znode1数据发生改变或节点被删除,客户端会得到这个节点/znode1的监控事件。如果/znode1再次改变,监控事件不会被发送,除非客户端再执行一次设置监控的读。
2、发送给客户端 这意味着事件在到达客户端的路上(通过网络),在这次变更操作的结果到达发起这次改变的客户端之前,事件可能没有到达客户端。监控被异步的发送到客户端。zk提供一种顺序保证:在看到监控事件以前,绝不能看到设置监控的改变。网络延迟或其它的因素,会导致客户端在不同的时间看到监控和结果代码。关键的是,不同的客户端看到的所有的事情有一个一致性的顺序。
3、设置监控的数据 这指的是节点可以改变的方式。想象zk维护两列监控:数据监控和子节点监控。getData()和exists()设置数据监控,getChildren()设置子节点监控。也可以
数据返回的类型
想象监控,
getData()和exists()返回节点的数据信息,而
getChildren()返回节点列表
。因此setData()将会触发节点设置的数据监控(假定设置成功)。成功的create()将会触发被创建节点的数据监控,和父节点的字节点监控。成功的delete()将会触发数据监控和子节点监控(对于父节点来说)。
监控在客户端连接到的服务器本地维护。这会让监控,设置,维护,分发轻量级。客户端连接到新的服务器时,监控会由于任何会话事件被触发。和服务器失去连接时,不能收到监控。当客户端重新连接时,任何之前注册的监控将会重新注册,如果需要的话触发。一般情况下,这些都会透明的发生。有一种监控会丢失的情况:对还没有创建节点的监控,在和服务器失去连接的情况下,节点被创建,然后被删除。
zk对监控的保证
考虑到监控,zk维护这些保证:
- 监控被排序,根据其它的事件、其它的监控和异步的回复。客户端库负责所有事情的分发。
- 客户端在看到节点新的数据之前,会得到这个节点的监控。
- 监控事件的顺序,对应从zk服务角度看到的更新顺序。
关于监控需要记住的事
- 监控是一次性的,如果你得到一个监控事件,并且想得到将来变更的通知,你必须设置另一个监控。
- 因为监控是一次性的,同时收到一个事件和设置新的监控之间有延迟,因此你不可能可靠的看到节点的每一次改变。准备好处理这种情况,收到事件和再一次设置监控之间,节点改变多次(你可能不注意,但要认识到这会发生)。
- 对于一个给定的通知,监控对象仅仅被触发一次。例如同一个监控对象被注册到exists()和getData调用(同一个节点),如果节点删除,对于节点删除的通知来说,监控对象仅仅被调用一次。
- 当和服务器失去连接,例如服务器宕机,直到连接重新建立,否则不能的到任何监控事件。由于这个原因,会话事件被发送给所有的外部监控句柄。使用会话事件来进入安全模式:失去连接时不能接收事件,因此你的进程在这种模式下应该保守的运行。