目录
5-Zookeeper的基础数据模型
5.1 Zookeeper节点存储
在Zookeeper中基础数据使用树形结构来存储对应源码中的类型为DataTree,树中的节点在这里称为znode对应源码中的类型为DataNode。
5.1.1 DataNode类型
DataNode类型主要用来存储节点的数据,主要包含的节点数据有,ACL访问控制,统计数据和子节点列表等,同时DataNode实现了Record接口来实现序列化和反序列化功能,关于Record在Zookeeper-jute子项目中有说明。了解了DataNode的作用,我们来看一下DataNode节点的设计。
成员变量 | 类型 | 说明 |
---|---|---|
digest | long | 根据其他成员变量使用DigestCalculator类型calculateDigest方法计算的摘要信息,用来检测数据是否被篡改过 |
digestCached | boolean | 标记此节点的摘要是否是最新的,用于优化性能。true为已缓存的,如果为false则在节点发生变更时会重新计算摘要 |
data | byte[] | 数据节点的数据 |
acl | Long | 此datanode的acl映射长度 |
stat | StatPersisted | 此节点持久化到磁盘的统计数据 |
children | Set | 此节点的子节点名字列表,不包含父级目录 |
EMPTY_SET | Set | 空集合列表,当子节点位空时候返回 |
5.1.2 StatPersisted
每个DataNode节点都会有一个StatPersisted类型的对象来记录当前节点持久化到磁盘的统计数据,那我们来看下每个节点进行了哪些统计信息:
成员变量 | 类型 | 说明 |
---|---|---|
czxid | long | 该数据节点被创建时的事务id |
mzxid | long | 该数据节点被修改时最新的事物id |
ctime | long | 该数据节点创建时间 |
mtime | long | 该数据节点最后修改时间 |
version | int | 当前节点版本号(可以理解为修改次数,每修改一次值+1) |
cversion | int | 子节点版本号(子节点修改次数,每修改一次值+1) |
aversion | int | 当前节点acl版本号(acl节点被修改次数,每修改一次值+1) |
ephemeralOwner | long | 临时节点标示,当前节点如果是临时节点,则存储的创建者的会话id(sessionId),如果不是,那么值= |
pzxid | long | 当前节点的父级节点事务ID |
与客户端交互的Stat统计数据类型与持久化统计数据类型的字段相似额外多了两个字段我们顺便来解释下:
成员变量 | 类型 | 说明 |
---|---|---|
dataLength | int | 当前节点数据长度 |
numChildren | int | 当前节点子节点个数 |
了解了DataNode节点后我们可以来看下Zookeeper的树形结构存储
5.1.3 DataTree
DataTree主要来维护节点的树形结构
成员变量 | 类型 | 说明 |
---|---|---|
LOG | Logger | slf4j标准化日志组件 |
RATE_LOGGER | RateLogger | 限流打印日志 |
nodes | NodeHashMap | 存放一个Path和其相关信息DataNode的映射,此映射提供了对数据节点的快速查找,每个节点的信息存储在这个映射关系中 |
dataWatches | IWatchManager | 数据监听管理器 |
childWatches | IWatchManager | 子节点监听管理器 |
nodeDataSize | AtomicLong | 缓存的所有数据节点的路径和数据的总大小 |
rootZookeeper | String | zookeeper树的根,值为/ |
procZookeeper | String | 作为管理和状态节点的zookeeper节点,值/zookeeper |
procChildZookeeper | String | 这将是作为root的子级存储的字符串,值zookeeper |
quotaZookeeper | String | zookeeper配额节点,用作zookeeper的配额管理节点,值为/zookeeper/quota |
quotaChildZookeeper | String | 值zookeeper |
configZookeeper | String | zookeeper的配置节点,值为:/zookeeper/config |
configChildZookeeper | String | 值为zookeeper |
pTrie | PathTrie | 根据路径实现的前缀树,可用于查询匹配节点路径 |
STAT_OVERHEAD_BYTES | int | znode的stat字段的大小。统计stat类的字段,主要用作监控使用对象的大小可以看Stat类型6个long类型 5个int类型这个字段的值为(6 * 8) + (5 * 4); |
ephemerals | Map<Long, HashSet> | sessionId与临时节点的hash表的映射关系,key为sessionid值为当前session的临时节点集合 |
containers | Set | 容器节点类型的集合 |
ttls | Set | ttl节点类型的集合 |
aclCache | ReferenceCountedACLCache | acl缓存信息的存储 |
DIGEST_LOG_LIMIT | int | 最大授权日志保留数量值为1024 |
DIGEST_LOG_INTERVAL | int | 对齐间隔,值为128,十六进制为80 |
digestFromLoadedSnapshot | ZxidDigest | 需要验证的摘要信息,如果这个值不为null,将寻找一个目标zxid |
lastProcessedZxidDigest | ZxidDigest | 与数据树中最高的zxid相关联的摘要 |
firstMismatchTxn | boolean | 标记变量,第一个不匹配的摘要信息,如果为true则将打印摘要日志。 |
digestWatchers | List | 摘要不匹配的时候通知订阅者 |
digestLog | LinkedList | 历史摘要列表 |
digestCalculator | DigestCalculator | 节点摘要计算器 |
5.1.4 NodeHashMap
了解了DataTree的基本结构可以详细来看下里面的重要成员,NodeHashMap类型的nodes对象 ,nodes对象类型是NodeHashMap接口,其对象初始化过程中通过创建子类型NodeHashMapImpl对象来实现,用于存放一个Path和其相关信息的映射. 那接下来我们来了解下NodeHashMapImpl是如何存储路径与节点的映射的。
字段 | 类型 | 说明 |
---|---|---|
nodes | ConcurrentHashMap<String, DataNode> | 路径节点映射 |
digestEnabled | boolean | 是否启用摘要:(仅Java系统属性:zookeeper.digest.enabled)3.6.0中的新功能:添加摘要功能,检测从磁盘加载数据库时ZooKeeper内部的数据不一致性,并跟踪领导,它基于中提到的adHash对数据树进行增量哈希检查 |
digestCalculator | DigestCalculator | 摘要计算工具类 |
hash | AdHash | 这个增量散列用于跟踪数据树的散列,以便我们可以快速验证事情是否同步。通过将每个新增节点的摘要值进行相加得到最后的hash值 |
通过类型我们可以了解到NodeHashMapImpl主要用于存储路径与节点映射关系和进行摘要计算。
后面我们会深度探索datatree节点处理流程
技术咨询与支持,可以扫描微信公众号进行回复咨询