• 【ZooKeeper】zookeeper源码2-持久化机制


    源码项目zookeeper-3.6.3:基础


    持久化机制是什么?
    是ZKDataBase本身在内存中,为了保证安全,需要把内存中数据持久化到磁盘,形成磁盘文件,所以涉及如何把相应的对象写到文件中去,称这种方式为持久化机制。
    持久化机制在zookeeper中没有提供专门的子项目,而是放在了zookeeper-server项目中org/apache/zookeeper/server/persistence,此路径下均为持久化类。

    在这里插入图片描述
    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

    ZooKeeper数据模型

    主要涉及两类知识:数据模型 和 持久化机制,其实就是两套 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    P1541 [NOIP2010 提高组] 乌龟棋
    软件测试的学习笔记(2)
    CI/CD 编译golang项目依赖包使用自建的gitlab仓库 免密码配置
    Java安全 CC链6分析
    Linux基本认识
    华为 2024 届实习校园招聘-硬件通⽤/单板开发——第八套
    [含毕业设计论文+PPT+源码等]ssm校友录网站+Java后台管理系统|前后分离VUE
    java基础加进阶学习笔记-------超详细的笔记(java基础知识)
    【用户画像】在ClickHouse中将宽表转换为bitmap表(源码实现)、用户分群架构设计、SpringBoot概述及使用
    电力移动应用及终端安全溯源管控技术研究与实践
  • 原文地址:https://blog.csdn.net/qq_36679460/article/details/127417531