zookeeper学习记录三(session,watcher,persit机制)
背景
继续前面的zookeeper学习的专题,这次主要是结合项目中遇到的一些问题,进一步学习了下zookeeper的一些内部机制。
?
针对以下几个问题:
1. zk是否可以保证watcher事件不丢失?
2. zk的EPHEMERAL节点的自动过期时间??
3. zk的如何保证节点数据不丢失?
?
如果你已经非常清楚这以上的几个问题,看官们可以不用往下看了。?
persit机制zookeeper中的persit机制主要是通过本地disk进行持久化,在本地disk上会有个memory数据对象保持同步。
?
持久化实现:
ZKDatabase
?
DataTree (内存树)zookeeper本身的数据结构就是一个树结构
数据模型(DataTree):
?
DataNode (1:n)data WatchManager (1:1,处理node节点的CRUD的变更事件,发送Watcher事件)child?WatchManager?(1:1, ?处理node子节点的变更事件,发送Watcher事件)sessions (ephemerals)DataNode模型:parent?data byte[]acl(安全)stat(审计信息)children整个实现相对比较简单,就是查找一个树节点后进行响应的操作?
FileTxnSnapLog (disk持久化)持久化数据分两类:?
?
TxnLog (类似于mysql/oracle的binlog/redolog)SnapShot (DataTree的数据镜像)刚开始最容易搞不清楚就是Txnlog和SnapShot的区别,SnapShot主要是定期对DataTree的数据做一个本地备份,TxnLog只是一些历史的版本变更日志(每次由写事件变化,就会写入到该日志中)。整个zk集群在处理数据变更过程中,会是先append变更信息到Txnlog中(此时会触发take snap操作),最后在FinalRequestProcessor中更新内存中的DataTree信息。
触发take snap的条件:
?
可能存在的问题:1. client向连接的server提交了watcher事件后,对应的server还未来得及提交给leader就直接出现了jvm crash,这时对应的watcher事件会丢失。(理论上正常关闭zookeeper server,不会存在该问题,需要客户端进行重试处理)2. client在发生一次failover时,可以自动对新的server的notification使用watcher set,可以通过设置jvm变量:zookeeper.disableAutoWatchReset进行,默认为false。如果为true,则不进行自动使用的行为)3. client出现session expired时,需要重新创建一个zookeeper client实例,此时对应的watcher set也会丢失,需要自己编码做一些额外的处理
zookeeper异常处理官方文档:http://wiki.apache. org/hadoop/ZooKeeper/FAQ
主要处理两个系统异常:
?
KeeperException.ConnectionLossException (client与其中的一台server socket链接出现异常)KeeperException.SessionExpiredException (client的session超过sessionTimeout为进行任何操作)ConnectionLossException可以通过重试进行处理,在ClientCnxn会根据你初始化ZooKeeper时传递的服务列表,自动尝试下一个server节点SessionExpiredException不能通过重试进行解决,需要应用重新new Zookeeper(),创建一个新的客户端,包括重新初始化对应的watcher,EPHEMERAL节点等。?
最后思路可能写的有点乱,文中所有的内容均通过阅读源码所得,如有不对的地方,尽情拍砖。