zookeeper 设计思考+基本介绍-2
Zookeeper 架构设计
1、中心化节点
2、数据同步---
3、leader选举
数据存储
磁盘
zookeeper 集群角色
-
leader
-
follower
-
observer - 只同步数,不参与选举、投票
Leader 角色
- 处理事务请求 和 非事务请求。 是事务请求的唯一处理者, 保证集群事务的 顺序性
- 集群内各服务器的调度者
Follower角色
- 处理非事务请求, 转发 事务请求 给 leader
- 参与 事务请求 的投票
- 参与 leader 选举的投票
Observer 角色
zookeeper 3.3 引入
- 不参与 投票
- 同步 数据
- 处理非事务请求
提升 集群 非事务处理的能力
这里关于节点复制的思考
为了 达到 分布式节点的强一致性,需要 实现分布式事务。
分布式事务的一致性协议有 2PC和3PC。
这里主要看2PC
当一个事务操作需要跨越多个分布式节点的时候,为了保持事 务处理的ACID特性,就需要引入一个“协调者”(TM)来统一调度所有分布式节点的执行逻辑,这些被 调度的分布式节点被称为AP。TM负责调度AP的行为,并最终决定这些AP是否要把事务真正进行提交; 因为整个事务是分为两个阶段提交,所以叫2PC(Two Phase Commitment Protocol)。

阶段一
1、事务询问
协调者 向 所有参与者 发送事务内容,徐文 是否可以执行事务的提交操作,并 等待各 参与者的响应
2、执行事务
各参与者节点执行事务操作,并将 undo和redo 信息 记录到事务日志种, 尽量把 提交过程种所有耗时的操作和准备 都 提前完成 确保 后面 100% 成功 提交事务
3、各参与者 向 协调者 反馈事务询问的
如果各参与者 成功执行了事务操作,则 反馈给 协调者 yes的响应,表示事务可以执行;
如果各参与者没有成功执行事务,则反馈给协调者 no的响应,表示事务不可执行
阶段二
协调者 根据 各参与者的反馈情况来 决定 最终是否可以进行事务操作, 即执行事务 或 中断事务。
zookeeper 采用 少数 服从多数的 方式来实现 数据同步, 这里 提升了整个集群的性能。
集群的 一般由 2*n+1 台 server组成,每台server 都维护了 内存状态镜像 和 持久化存储的 事务日志和快照。
zookeeper 一致性模型
顺序一致性模型, 并非强一致。
是否存在关于读取一致性问题??如果客户端访问了还未同步 的节点?
这里 zookeeper做了处理,客户端会记录已经处理的zxid, 会与 zk 节点 进行比较
ZAB 协议
支持 奔溃恢复的 原子广播协议。
节点基于 心跳机制 传播
两种模式:
- 崩溃恢复- leader选举 (过半投票)
- 原子广播-数据同步
消息广播原理
简化版的 2PC过程
1、leader 收到事务请求后,将消息 赋予 一个 全局唯一的 64位自增id- zxid, 通过 zxid 来实现因果有序保证
2、leader为每个follower准备了一个 FIFO队列,将带有 zxid 的消息作为一个 提案(proposal),分发给 所有的follower
3、当 follower接收到 proposal后,先 把 proposal 写入 磁盘,写入成功后, 响应一个 ACK
4、当leader 接受到合法数量 的 ACK 后,leader 就会向这些 follower 发送 commit 命令, 同时 会在本地执行该消息
5、当 follower 接受 消息的commit 命令后,提交消息
ZAB 协议不能终止事务,只需要保证过半的节点响应了就行,替身了集群的整体性能,但是在某个时刻存在follower和leader节点 状态不一致的情况,zk 通过 zxid 来进行处理。
奔溃恢复
在这里需要完成两件事:
- leader 选举
- 数据同步
两个保证:
-
已经被处理的消息不能丢弃
-
被丢弃的消息不能再出现
ZXID
64位的数字,
高32位是 epoch, 标识 leader成功选举的周期数,
低32位 代表 当前 epoch的 所接收的事务消息数
zookeeper 的事务日志
zookeeper的数据是持久化在磁盘上的,默认目录是 /tmp/zookeeper 下,存放事务日志和快照日志。
# 内存数据库快照存放地址
dataDir=/data/zookeeper-3.4.6/data
# 事务日志存储
dataLogDir=/data/zookeeper-3.4.6/data/log
文件命名为 log.zxid, 其中 zxid 为当前日志文件种开始记录的第一条数据的zxid。
查看事务日志文件的命令
java -cp :/data/program/apache-zookeeper-3.6.1-bin/lib/slf4j-api1.7.25.jar:/data/program/apache-zookeeper-3.6.1-bin/lib/zookeeper-jute3.6.1.jar:/data/program/apache-zookeeper-3.6.1-bin/lib/zookeeper-3.6.1.jar
org.apache.zookeeper.server.LogFormatter log.1
查看 快照文件的命令
java -cp :/data/program/apache-zookeeper-3.6.1-bin/lib/slf4j-api1.7.25.jar:/data/program/apache-zookeeper-3.6.1-bin/lib/zookeeper-jute3.6.1.jar:/data/program/apache-zookeeper-3.6.1-bin/lib/zookeeper3.6.1.jar:/data/program/apache-zookeeper-3.6.1-bin/lib/snappy-java-1.1.7.jar
org.apache.zookeeper.server.SnapshotFormatter snapshot.0
Leader 选举原理
选举的相关因素
epoch / zxid / myid
选举状态
LOOKING: 竞选状态
FOLLOWING: 跟随着状态
OBSERVING: 观察者状态,不参与投票
LEADING:领导者状态
服务器启动时的leader选举
每个节点启动时,都是 LOOKING状态
-
每个server发出 一个投票. 都以自己作为 leader 来进行投票, 每次投票 都会包含所 投票服务器的(myid,zxid,epoch),
-
接受来自各服务器的投票.集群中的服务器收到投票后, 先判断 投票的 有效性,(是否本轮投票epoch, 是否来自 LOOKING 状态的服务器)
-
处理投票. 这对每个投票,服务器都会将 别人的投票 和 自己的投票进行比较:
- epoch 比较
- 检查 zxid, 大的作为leader
- 比较 myid, 大的作为 leader
-
统计投票. 每次投票后,统计投票信息,判断是否有过半的机器接受奥相同的 投票信息 .
-
更改服务器的状态.
leader宕机或不可用时的leader选举
整个集群 无法对外提供服务,进入 leader选举
1.变更状态. 所有 非 observer 节点 将自己的服务器状态改成 LOOKING, 进入 leader选举.
2.同 服务器启动时的leader选举.

浙公网安备 33010602011771号