概述

ZooKeeper是一种集中式服务,用于维护配置信息,命名,提供分布式同步和提供组服务。所有这些类型的服务都以分布式应用程序的某种形式使用。每次实施它们都需要做很多工作来修复不可避免的错误和竞争条件。由于难以实现这些类型的服务,应用程序最初通常会吝啬它们,这使得它们在变化的情况下变得脆弱并且难以管理。即使正确完成,这些服务的不同实现也会在部署应用程序时导致管理复杂性。

ZK集群架构设计


ZK主要分为三种角色:

  • Leader(领导者):一个Zookeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各 Follwer及Observer间的心跳。所有的写操作必须要通过Leader完成再由Leader将写操作广播给其它服务器。
  • Follower(跟随者):一个Zookeeper集群可能同时存在多个Follower,它会响应Leader的心跳。Follower 可以处理客户端的读请求,但写请求转发给Leader处理,并且负责参与新 leader的选举、响应 leader 的提议。
  • Observer(观察者):无投票权,不参加选举, 也不响应提议。Observer不需要将事务持久化到磁盘,如 果重启需要从 leader 重新同步整个名字空间。

ZK特性:

  • 顺序一致性
  • 实时性
  • 原子性

ZK数据结构与存储

ZK数据结构模型


节点存储容量不能超过1M。
ZNode节点类型:
Znode的分为四类:

  • 持久节点(persistent node):节点会被持久化处理,执行命令: create /apps/app1 “order” 。
  • 临时节点(ephemeral node):客户端断开连接后,ZooKeeper会自动删除临时节点, 执行命令: create -e /apps/app1 “order” 。
  • 顺序节点(sequential node):每次创建顺序节点时,ZooKeeper都会在路径后面自动添加上10位的数 字,从1开始,最大值为2147483647 (2^32-1),每个顺序节点都有一个单独的计数器,并且单调递增 的,由 leader 实例维护,执行命令: create -s /apps/app1 “order” 。
  • 临时顺序节点(EPHEMERAL_SEQUENTIAL):基本特性与临时节点一致,创建节点的过程中,zookeeper 会在其名字后自动追加一个单调增长的数字后缀,作为新的节点名。
    ZNode节点属性:
[zk:    localhost:2181(CONNECTED)    1]    get    /testNode test 
cZxid    =    0x2 
ctime    =    Fri    Aug    06    22:28:23    CST    2020 
mZxid    =    0x2 
mtime    =    Fri    Aug    06    22:28:23    CST    2020 
pZxid    =    0x2 
cversion    =    0 
dataVersion    =    0 
aclVersion    =    0 
ephemeralOwner    =    0x0 
dataLength    =    4 
numChildren    =    0

ZK数据存储方式

数据存储方式分为三类:
1.内存数据


内存数据结构分为三类:

  • DataTree: 内存数据存储的核心
  • DataNode: 数据存储的最小单元
  • ZKDatabase: ZK的内存数据库

2. 事务日志
事务日志处理流程:

事务日志文件内容示例:
查看日志命令:

java ‐classpath .:./lib/slf4j‐api‐1.7.25.jar:./zookeeper‐3.4.14.jar org.apache.zookeeper.server.LogFormatter /data/zookeeper/version‐2/log.100000001 > log1.log

产生日志内容:

3/14/22 8:55:19 PM EDT session 0x20003a778cc0012 cxid 0xa9 zxid 0x1000001bc delete '/lock‐ namespace/shared_lock/order/W‐0000000016 
3/14/22 8:55:29 PM EDT session 0x20003a778cc0012 cxid 0xb0 zxid 0x1000001bd delete '/lock‐ namespace/shared_lock/order/W‐0000000017 
3/14/22 9:46:18 PM EDT session 0x20003a778cc0012 cxid 0xb1 zxid 0x1000001be create '/lock‐ namespace/shared_lock/order/W-0000000018,#3139322e3136382e3132332e313033,v{s{31,s{'world,'anyone}}},T,19 
3/14/22 9:46:38 PM EDT session 0x20003a778cc0012 cxid 0xb4 zxid 0x1000001bf delete '/lock‐ namespace/shared_lock/order/W‐0000000018

3. 数据快照(snapshot)
数据快照用来记录Zookeeper服务器上某一时刻的全量内存数据内容,并将其写入指定的磁盘文件中。 Zookeeper在进行若干次事务日志记录后,将内存数据库的全量数据Dump到本地文件中,这个就是数据快照
快照查看命令:

java ‐classpath .:./lib/slf4j‐api‐1.7.25.jar:./zookeeper‐3.4.14.jar org.apache.zookeeper.server.SnapshotFormatter /data/zookeeper/version‐2/snapshot.100000000 > snap1.log

其处理步骤如下:

  1. 检查是否需要进行数据快照,每一次事务日志记录之后,Zookeeper都会检测是否需要进行数据快照, 考虑到数据快照对于Zookeeper机器的影响,需要尽量避免ZK集群中的所有机器在同一时刻进行数据快照。 采用过半随机策略进行数据快照操作。
  2. 切换事务日志文件,表示当前的事务日志已经写满,需要重新创建一个新的事务日志。
  3. 创建数据快照的异步线程,创建单独的异步线程来进行数据快照以避免影响Zookeeper主线程的运行状态。
  4. 获取全量数据和会话信息,从ZKDatabase数据库中获取到DataTree和会话信息。
  5. 生成快照数据文件名,ZK根据当前已经提交的最大ZXID来生成数据快照文件名。
  6. 数据序列化,首先序列化文件头信息,然后再对会话信息和DataTree分别进行序列化,同时生成一个 Checksum校验文件,一并写入快照文件中。
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐