首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

zookeeper学习记要三(session,watcher,persit机制)

2012-07-26 
zookeeper学习记录三(session,watcher,persit机制)背景继续前面的zookeeper学习的专题,这次主要是结合项目

zookeeper学习记录三(session,watcher,persit机制)
背景

继续前面的zookeeper学习的专题,这次主要是结合项目中遇到的一些问题,进一步学习了下zookeeper的一些内部机制。

?

针对以下几个问题:

1. zk是否可以保证watcher事件不丢失?

2. zk的EPHEMERAL节点的自动过期时间??

3. zk的如何保证节点数据不丢失?

?

如果你已经非常清楚这以上的几个问题,看官们可以不用往下看了。?

persit机制

zookeeper中的persit机制主要是通过本地disk进行持久化,在本地disk上会有个memory数据对象保持同步。

?

持久化实现:

ZKDatabase

?

DataTree (内存树)
FileTxnSnapLog (disk持久化)committedLog (FileTxnSnapLog的一份内存数据cache,默认存储500条变更记录)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只是一些历史的版本变更日志(每次由写事件变化,就会写入到该日志中)。
下面看一下,zookeeper在新节点启动后,是否如何保证数据一致:?
    首先节点启动后,尝试读取本地的SnapShot log数据(zkDb.loadDataBase()),反序列化为DataTree对象,并获取last zxid。?follower启动后会向leader发送自己的last zxidleader收到zxid后,对比自己当前的ZKDatabase中的last zxid
    如果当前follower的zxid在内存committedLog中,直接将内存中的committedLog提取出来进行发送,否则将当前的DataTree直接发送给follower.(不再是发送变更记录)
    数据同步完成后,follower会开始接收request请求
一致性机制

整个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节点等。

?

最后

思路可能写的有点乱,文中所有的内容均通过阅读源码所得,如有不对的地方,尽情拍砖。

热点排行