Bootstrap

大数据开发之zookeeper的数据与存储

一、内存数据

zk的数据模型是树结构,在内存数据库中,存储了整棵树的内容,包括所有的节点路径、节点数据、ACL信息,zk会定时将这个数据存储到磁盘上

1.1 DataTree

DataTree是内存数据存储的核心,是一个树结构,代表了内存中一份完整的数据。DataTree不包含任何与网络、客户端连接及请求处理相关的业务逻辑,是一个独立的组件。

1.2 DataNode

DataNode是数据存储的最小单元,其内部除了保存了结点的数据内容、ACL列表、节点状态之外,还记录了父节点的引用和子节点列表两个属性,其也提供了对子节点列表进行操作的接口。

1.3 ZKDatabase

zk的内存数据库,管理zk的所有会话、DataTree存储和事务日志。ZKDatabase会定时向磁盘dump快照数据,同时在zk启动时,会通过磁盘的事务日志和快照文件恢复成一个完整的内存数据库。

二、事务日志

2.1 日志写入

FileSnap负责维护快照数据对外的接口,包括快照数据的写入和读取等,将内存数据库写入快照数据文件其实是一个序列化过程。针对客户端的每一次事务操作,zk都会将他们记录到事务日志中,同时也会将数据变更应用到内存数据库中,zk在进行若干次事务日志记录后,将内存数据库的全量数据Dump到本地文件中,这就是数据快照。其步骤如下;

1.确定是否需要进行数据快照。每进行一次事务日志记录之后,zk都会检测当前是否需要进行数据快照,考虑到数据快照对于zk机器的影响,需要尽量避免zk集群中的所有机器在同一时刻进行数据快照。采用过半随机策略进行数据快照操作。

2.切换事务日志文件。表示当前的事务日志已经写满,需要重新创建一个新的事务日志。

3.创建数据快照异步线程。创建单独的异步线程来进行数据快照以避免影响zk主流程。

4.获取全量数据和会话信息。从ZKDatabase中获取到DataTree和会话信息。

5.生成快照数据文件名。zk根据当前已经提交的最大ZXID来生成数据快照文件名。

6.数据序列化。首先序列化文件头信息,然后再对会话信息和DataTree分别进行序列化,同时生成一个Checksum,一并写入快照数据文件中去。

四、数据初始化

在zk服务器启动期间,首先会进行数据初始化工作,用于将存储在磁盘上的数据文件加载到zk服务器内存中。

4.1 初始化流程

zk的初始化过程如下图所示;

 

数据的初始化工作是从磁盘上加载数据的过程,主要包括了从快照文件中加载快照数据和根据实物日志进行数据修正两个过程。

10.事务应用。获取大于zxid_for_snap的事务后,将其逐个应用到之前基于快照数      据文件恢复出来的DataTree和sessionsWithTimeouts。每当有一个事务被应用      到内存数据库中后,zk同时会回调PlayBackListener,将这事务操作记录转换成      Proposal,并保存到ZKDatabase的committedLog中,以便Follower进行快速      同步。

11.获取最新的ZXID。待所有的事务都被完整地应用到内存数据库中后,也就基本       上完成了数据的初始化过程,此时再次获取ZXID,用来标识上次服务器正常运行     时提交的最大事务ID。

12.校验epoch。epoch标识了当前Leader周期,集群机器相互通信时,会带上这个      epoch以确保彼此在同一个Leader周期中。完成数据加载后,zk会从步骤11中        确定ZXID中解析出事务处理的Leader周期:epochOfZxid。同时也会从磁盘的      currentEpoch和acceptedEpoch文件中读取上次记录的最新的epoch值,进行        校验。

五、数据同步

5.1 同步流程

整个集群完成Leader选举后,Learner会向Leader进行注册,当Learner向Leader完成注册后,就进入数据同步环节,同步过程就是Leader将那些没有在Learner服务器上提交过的事务请求同步给Learner服务器,大体过程如下

 

原创作者:徐卖狼