Zookeeper
计算机知识思维导图:Zookeeper。网页展示前三层结构,可在线查看完整脑图并下载 GoMind 文件。
2026-08-25
## Zookeeper ### Zookeeper #### 崩溃恢复过程 ##### 1. 各个节点向其他节点发起投票,投票当中包含自己的服务器ID及最新事务ID(ZXID),此时处于Looking状态 ##### 2. 节点会用自身的ZXID 与其他节点的ZXID做比较,如果发现其他节点的ZXID比较大,则重新发起投票(ZXID相同则取ID最大的),投票给目前已知最大的ZXID所属节点 ##### 3. 每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票,该节点将会成为准leader, 状态变为 Leading, 其他节点为 Following ##### 4. 发现阶段,检查是否有多个leading状态的节点,即leading接收Followler发来的各自的最新的epoch值,leading从中选出最大的epoch值,基于此值加一,生成新的epoch分发给各个Follower,各个Follower 收到最新epoch后返回ACK给leading 节点,带上各自最大的ZXID和历史事务日志 ##### 5. 同步阶段,把leader 刚才收集到的最新历史事务日志,同步给集群中所有的Follower, 只有当过半数的Follower同步成功,这个leading状态的节点才会成为正式的Leader #### 数据顺序一致性 #### 设计目标 ##### 1. 简单的数据模型 ##### 2. 可以构建集群 ##### 3. 顺序访问 ##### 4. 高性能 #### 集群角色 ##### Leader ##### Follower ##### Observer #### ZAB协议 ##### 数据同步 ##### ZXID ##### 两种模式 #### 应用 ##### Canal ##### Hadoop ##### HBase ##### Kafka ##### Dubbo #### 定义 ##### 一个分布式的,开放源码的分布式应用程序协 调服务。为分布式应用提供一致性服务 #### 节点类型 ##### 临时节点 ##### 临时顺序节点 ##### 持久节点 ##### 持久顺序节点 > 仅展示前三层结构;请在线查看完整脑图或下载 GoMind 文件。
Zookeeper
Zookeeper
起源于雅虎研究院的一个研究小组。是chubby的开源实现。设计的目标是将那些复杂而容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。 所有读操作由 Follower 节点完成,而所有的写操作全部交由主节点完成. 全量数据存储在内存中 基本概念: 数据快照:数据快照是zk数据存储中另一个非常核心的运行机制。数据快照用来记录zk服务器上某一时刻的全量内存数据内容,并将其写入到指定的磁盘文件中,可通过dataDir配置文件目录。可配置参数snapCount,设置两次快照之间的事务操作个数,zk节点记录完事务日志时,会统计判断是否需要做数据快照(距离上次快照,事务操作次数等于snapCount/2~snapCount 中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群影响缓慢)。
1. 各个节点向其他节点发起投票,投票当中包含自己的服务器ID及最新事务ID(ZXID),此时处于Looking状态
2. 节点会用自身的ZXID 与其他节点的ZXID做比较,如果发现其他节点的ZXID比较大,则重新发起投票(ZXID相同则取ID最大的),投票给目前已知最大的ZXID所属节点
3. 每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票,该节点将会成为准leader, 状态变为 Leading, 其他节点为 Following
4. 发现阶段,检查是否有多个leading状态的节点,即leading接收Followler发来的各自的最新的epoch值,leading从中选出最大的epoch值,基于此值加一,生成新的epoch分发给各个Follower,各个Follower 收到最新epoch后返回ACK给leading 节点,带上各自最大的ZXID和历史事务日志
5. 同步阶段,把leader 刚才收集到的最新历史事务日志,同步给集群中所有的Follower, 只有当过半数的Follower同步成功,这个leading状态的节点才会成为正式的Leader
崩溃恢复过程
两种情况会执行选举 1. 服务启动阶段 2. 主节点出故障
数据顺序一致性
1. 简单的数据模型
数据树,由一系列称为ZNode的数据节点组成。 将全量数据放到内存中,以此来实现高吞吐、低延迟
2. 可以构建集群
3. 顺序访问
每个更新请求都会分配一个全局唯一的递增事务ID,以此编号来保证事务操作的先后顺序
4. 高性能
全量数据存储在内存中
设计目标
Leader
为客户端提供读写服务
Follower
提供读服务,参与Leader选举过程,参与过半写成功策略
Observer
仅提供读服务,不参与Leader选举过程,也不参与“过半写成功”策略。可以在不影响写性能的情况下提成集群的读性能
集群角色
数据同步
Leader服务器会为每一个Follower服务器都准备一个队列,并将那些没有被Follower服务器同步的事务以Proposal消息的形式逐个发送给Follower服务器,并在每一个Proposal消息紧接着再发送一个Commit消息,以表示该事务已经被提交。 等到Follower服务器将所有其尚未同步的事务都从Leader服务器上同步过来并成功应用到本地数据库中后,Leader就会将该Follower加入到真正的可用Follower列表中 选主后,节点需要切换状态,leader切换成LEADING状态后的流程如下: (1)重新加载本地磁盘上的数据快照至内存,并从日志文件中取出快照之后的所有事务操作,逐条应用至内存,并添加到已提交事务缓存commitedProposals。这样能保证日志文件中的事务操作,必定会应用到leader的内存数据库中。 (2)获取learner发送的FOLLOWERINFO/OBSERVERINFO信息,并与自身commitedProposals比对,确定采用哪种同步方式,不同的learner可能采用不同同步方式(DIFF同步、TRUNC+DIFF同步、SNAP同步)。这里是拿learner内存中的zxid与leader内存中的commitedProposals(min、max)比对,如果zxid介于min与max之间,但又不存在于commitedProposals中时,说明该zxid对应的事务需要TRUNC回滚;如果 zxid 介于min与max之间且存在于commitedProposals中,则leader需要将zxid+1~max 间所有事务同步给learner,这些内存缺失数据,很可能是因为leader切换过程中造成commit消息丢失,learner只完成了事务日志写入,未完成提交事务,未应用到内存。 (3)leader主动向所有learner发送同步数据消息,每个learner有自己的发送队列,互不干扰。同步结束时,leader会向learner发送NEWLEADER指令,同时learner会反馈一个ACK。当leader接收到来自learner的ACK消息后,就认为当前learner已经完成了数据同步,同时进入“过半策略”等待阶段。当leader统计到收到了一半已上的ACK时,会向所有已经完成数据同步的learner发送一个UPTODATE指令,用来通知learner集群已经完成了数据同步,可以对外服务了。
ZXID
由64位的数字组成,低32位是一个简单的单调递增计数器,高32位代表Leader周期 epoch的编号。 每当选举产生一个新的Leader就会从集群中取出最大的ZXID,并从中解析出epoch, 然后加一操作,再将低32位置0
客户端将写入数据申请发送到任意Follower
Follower将写入请求转发给Leader
Leader采用两阶段提交方式,先发送Prapose
(带上最新的ZXID)广播给各Follower
Follower接收到Prapose后将该请求加入到消息历史
队列(history queue),并返回ACK消息给Leader
当leader收到大多数follower(超过法定数量)的ack消息,leader会发送commit请求
当follower收到commit请求时,会判断该事务的ZXID是不是比历史队列中的任何事务的ZXID都小,如果是则提交,如果不是则等待比它更小的事务的commit
消息广播
确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交
确保丢弃那些只在Leader服务器上被提交的议案
如Leader发起提案后就崩溃,则在Leader恢复后需要保证这个提案已丢弃
基本特性
选主
发现
1. 重新加载本地磁盘上的数据快照至内存,并从日志文件中取出快照之后的
所有事务操作,逐条应用至内存,并添加到已提交事务缓存commitedProposals。
这样能保证日志文件中的事务操作,必定会应用到leader的内存数据库中。
DIFF同步
如果 zxid 介于min与max之间且存在于commitedProposals中,则leader需要将zxid+1~max 间所有事务同步给learner,这些内存缺失数据,很可能是因为leader切换过程中造成commit消息丢失,learner只完成了事务日志写入,未完成提交事务,未应用到内存
TRUNC+DIFF同步
这里是拿learner内存中的zxid与leader内存中的commitedProposals(min、max)比对,如果zxid介于min与max之间,但又不存在于commitedProposals中时,说明该zxid对应的事务需要TRUNC回滚
SNAP同步
2. 获取learner发送的FOLLOWERINFO/OBSERVERINFO信息,并与自身commitedProposals比对,确定采用哪种同步方式,不同的learner可能采用
不同同步方式(DIFF同步、TRUNC+DIFF同步、SNAP同步)
leader主动向所有learner发送同步数据消息,每个learner有自己的发送队列,互不干扰。
同步结束时,leader会向learner发送NEWLEADER指令,同时learner会反馈一个ACK。当leader接收到来自learner的ACK消息后,就认为当前learner已经完成了数据同步,同时进入“过半策略”等待阶段。当leader统计到收到了一半已上的ACK时,会向所有已经完成数据同步的learner发送一个UPTODATE指令,用来通知learner集群已经完成了数据同步,可以对外服务了。
同步
广播
四个阶段
崩溃恢复
当Leader服务器出现崩溃退出或机器重启,或集群中已经不存在过半的服务器与该Leader服务器保存正常通讯,就会进入到该状态,为保存程序正确运行需要选举出一个新的Leader服务器
两种模式
ZAB协议
Zookeeper Atomic Broadcast (Zookeeper原子广播),Zookeeper 是通过 Zab 协议来保证分布式事务的最终一致性。 两种基本模式 1. 崩溃恢复 2. 消息广播
Canal
基于mysql binlog的增量订阅和消费组件
Hadoop
zk在hadoop主要用于实现高可用
HBase
Hadoop Database 是google Bigtable的开源实现,是一个基于文件系统设计的面向海量数据的高可靠、高性能、可伸缩的分布式存储系统。 zk用作分布式协调服务
Kafka
LinkedIn 2010年12月开源的分布式消息系统。主要用于实现低延迟的发送和收集大量的事件及日志数据,是一个吞吐量极高的分布式消息系统
Dubbo
zk用作注册中心
应用
发布订阅(配置中心)
负载均衡
命名服务
分布式协调/通知
集群管理
Master选举
分布式锁
分布式队列
一个分布式的,开放源码的分布式应用程序协
调服务。为分布式应用提供一致性服务
定义
临时节点
临时节点的生命周期和客户端会话绑定,也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉
临时顺序节点
持久节点
所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点,也就是说不会因为创建该节点的客户端会话失效而消失
持久顺序节点
节点类型