在介绍ZKDatabase.loadDataBase()前先简要介绍一下以下几个类
1.DataNode
DataNode主要存储了以下几个属性(详情可看DataNode类)
DataNode parent;//父节点信息
byte data[];//本节点数据
Long acl;//ACL权限控制转换为long后的值
public StatPersisted stat;//持久化到磁盘后节点的stat信息
private Set<String> children = null;//子节点的集合
2.DataTree
DataTree有以下几个主要的属性
//路径与节点的映射,能够通过路径(path)快速获取节点信息
private final ConcurrentHashMap<String, DataNode> nodes =
new ConcurrentHashMap<String, DataNode>();
//监听(Watch)节点数据变化
private final WatchManager dataWatches = new WatchManager();
//监听子节点变化
private final WatchManager childWatches = new WatchManager();
//路径字典树,实现了hierarchal namespace
private final PathTrie pTrie = new PathTrie();
说完以上内容后,接下来具体描述loadDataBase()的过程
1.从dataDir目录下version-2里按照文件降序(倒序)取得最多100个类似snapshot.xxx的文件。
2.按照倒序遍历这些文件并且反序列化到内存树(datatree)中直到找到第一个有效的snapshot文件才结束,然后将该有效文件的zxid(相当于snapshot.xxx中的xxx)作为datatree.lastProcessedZxid存起来.此时,数据快照文件反序列化到内存数据库datatree结束。
3.从lastProcessedZxid+1开始找txnLog(dataLogDir),将不小于lastProcessedZxid+1的文件和zxid小于lastProcessedZxid+1但是最接近lastProcessedZxid+1的文件存入storedFiles。
4.迭代遍历storedFiles的每个文件,将文件转为InputArchive对象 ,并通过该对象反序列化到hdr(事务头)和txn(事务体record)中。
5.迭代每个事务日志(hdr+txn),将其存入datatree中,通过addCommittedProposal提交Proposal 。
6.得到最新的zxid。内存数据库datatree初始化完毕。