Zookeeper深入理解(二)(编程实践之故障处理)

JerryXia 发表于 , 阅读 (0)
Zookeeper会对所有连接它的Client表现出一致的状态,当一个Client收到Zookeeper的一个响应时,它会相信其他Client收到的响应将是一致的,但如果ZK Client Library与Zookeeper服务断开连接,将不能再保证信息的一致性,这时ZK Client Library将发布Disconnected事件和ConnectionLossException异常。当然,ZK Client Library会尽力尝试摆脱这种情形,它将持续尝试连接另一个Server,直到和Server重新建立连接,一旦会话建立,Zookeeper将生成SyncConnected事件并开始处理请求,这是Zookeeper将重新注册之前注册的监听器,并且对于在连接断开期间发生的变化,生成监听事件。典型的Disconnected事件和ConnectionLossException异常都是Zookeeper服务器故障。下图阐述了这种问题connect-loss.jpg如果Client没有任何待处理的请求,Connection Loss很少会中断Client,除了发生Disconnected事件,接着SyncConnected事件外,Client不会收到任何状态改变通知。但是当Client有待处理的请求时,则要麻烦得多。比如下面的场景zk-connection-loss-revenge.jpgClient c1将称为Leader,但是在t1时刻丢失了连接,但知道t4时刻它才知道自己已经被声明为崩溃,同时它的会话在t2时刻已经过期,并且在t3时刻,Client c2变成了Leader,即t2~t4,Client c1不知道自己已经被声明为崩溃并且Leader已经转变为Client c2。因此,当应用收到Disconnected事件时,直到应用再次连接上Zookeeper前,应该暂停作为Leader的操作,正常情况下,重连接操作会很快。

exists监听和Disconnected事件

为了让会话断开和重连能够更无缝一些,ZK Client Library将在新的server上重建任何存在的监听器。当ZK Client Library连接Server时,它会发送未触发的监听器列表最新的zxid给Server,Server会检查监听器及其对应的节点的更新时间戳,如果节点的更新时间戳在该zxid之后,Server将触发该监听器。但要排除exists操作,因为exists可以监听一个不存在的节点。但还是会出现丢失创建事件的情况,如下图,Client c2就丢失了节点/event创建的事件。zk-notification-corner-case.jpg

不可恢复的故障

不可恢复的故障通常是由于会话过期导致,或者是已授权的会话不再被授权。这种两种情况,Zookeeper将丢弃会话状态。处理不可恢复的故障最简单的办法就是终止进程和重启,这使得进程可以恢复,并且通过新的会话重新初始化其状态。