ZK内提供了一个ZKDatabase的数据库,负责维护znode数据模型
持久化ZKDatabase的方式:定期拍摄快照
ZKDatabase的内部,维护了一棵树:DataTree,每个节点叫做DataNode,
具体表现,遍历DataTree,把一个一个DataNode对象写入磁盘文件,序列化
接口SnapShot拍摄快照和冷启动恢复,内存到:序列化serialize、反序列化deserialize
接口TxnLog记录操作日志:追加append、提交commit、回滚rollLog
SnapShot和TxnLog统一成一个类FileTxnSnapLog
FileTxnSnapLog两个成员变量:SnapShot、TxnLog
save方法进行保存快照(DataTree),调用serialize
restore恢复DataTree,调用deserialize
ZKDatabase维护了:
1、FileTxnSnapLog 提供相关动作实现
2、DataTree 内存中所有数据
FileSnap实现了SnapShot完成了,SnapShot的功能实现
FileTxnLog实现了TxnLog
主要涉及两类知识:数据模型 和 持久化机制,其实就是两套 API
1、数据模型:DataTree + DataNode
2、持久化机制:FileTxnSnalLog = TxnLog + SnapLog
3、zk数据库:ZKDataBase = DataTree + FileTxnSnalLog(即 ZKDataBase 对象的内部有两个成员变量DataTree + FileTxnSnapLog)
抽象出了重要的三个 API 用来完成数据的管理:
1、DataNode znode 系统中的一个节点的抽象
2、DataTree znode 系统的完整抽象
3、ZKDataBase 负责管理 DataTree,处理最基本的增删改查的动作,执行 DataTree 的相关快照和恢复的操作
关于 ZooKeeper 中的数据在内存中的组织,其实就是一棵树:
1、DataTree (抽象了一棵树)
2、DataNode (抽象一个节点)
3、管理这个 DataTree 的组件就是 ZKDataBase (内存数据库:针对 DataTree 能做各种操作)
ZooKeeper 本身是一个对等架构(内部选举,从所有 Learner 中选举一个 Leader, 剩下的成为 Follower)
1、每个节点上都保存了整个系统的所有数据(leader存储了数据,所有的follower节点都是leader的副本节点)
2、每个节点上的都把数据放在磁盘一份,放在内存一份
主要的类:
第一组:主要是用来操作日志的(如果客户端往 ZooKeeper 中写入一条数据,则记录一条日志)
TxnLog,接口,读取事务性日志的接口
FileTxnLog,实现 TxnLog 接口,添加了访问该事务性日志的 API
第二组:拍摄快照(当内存数据持久化到磁盘)
Snapshot,接口类型,持久层快照接口
FileSnap,实现 Snapshot 接口,负责存储、序列化、反序列化、访问快照
第三组;两个成员变量:TxnLog 和 SnapShot
FileTxnSnapLog,封装了 TxnLog 和 SnapShot
第四组:工具类
Util,工具类,提供持久化所需的API
ZooKeeper 的数据模型系统的伪代码表示:
class ZKDataBase{
protected DataTree dataTree;
protected FileTxnSnapLog snapLog;
}
class DataTree{
//根节点
private static final String rootZookeeper = "/";
// 所有节点的 路径 和 节点抽象的 映射
private final NodeHashMap nodes = new NodeHashMapImpl(digestCalculator){
private final ConcurrentHashMap<String, DataNode> nodes;
}
}
public class DataNode implements Record {
byte[] data;
private Set<String> children = null;
}
class FileTxnSnapLog{
TxnLog txnLog;
SnapShot snapLog;
}
// 实现类:
interface TxnLog{
void rollLog() throws IOException;
boolean append(TxnHeader hdr, Record r) throws IOException;
boolean truncate(long zxid) throws IOException;
void commit() throws IOException;
}
// 实现类:
interface SnapShot{
long deserialize(DataTree dt, Map<Long, Integer> sessions) throws IOException;
void serialize(DataTree dt, Map<Long, Integer> sessions, File name, boolean fsync) throws IOException;
}