导图社区 Zookeeper
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
编辑于2022-06-26 10:13:30Zookeeper
基础操作
1.Zookeeper入门
概述
Zookeeper 是一个开源的分布式的,为分布式框架提供协调服务的 Apache 项目。 工作机制: Zookeeper从设计模式角度来理解:是一个基 于观察者模式设计的分布式服务管理框架,它负 责 存储和管理大家都关心的数据,然 后接受观察者的 注 册,一旦这些数据的状态发生变化,Zookeeper 就 将负责通知已经在Zookeeper上注册的那些观察 者做出相应的反应。
特点
1)Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。 2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所 以Zookeeper适合安装奇数台服务器。 3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。 4)更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。 5)数据更新原子性,一次数据更新要么成功,要么失败。 6)实时性,在一定时间范围内,Client能读到最新数据。
数据结构
ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个 节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过 其路径唯一标识。 
应用场景
提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下 线、软负载均衡等。
统一命名服务
在分布式环境下,经常需要对应用/服 务进行统一命名,便于识别。 例如:IP不容易记住,而域名容易记住。 
统一配置管理
1)分布式环境下,配置文件同步非常常见。 (1)一般要求一个集群中,所有节点的配置信息是 一致的,比如 Kafka 集群。 (2)对配置文件修改后,希望能够快速同步到各个 节点上。 2)配置管理可交由ZooKeeper实现。 (1)可将配置信息写入ZooKeeper上的一个Znode。 (2)各个客户端服务器监听这个Znode。 (3)一 旦Znode中的数据被修改,ZooKeeper将通知 各个客户端服务器。 
统一集群管理

服务器动态上下线
客户端能实时洞察到服务 器上下线的变化 
软负载均衡
在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求 
下载地址
2.安装
本地模式安装
配置参数解读
3.Zookeeper集群操作
集群操作
集群安装
选举机制
 SID:服务器ID。用来唯一标识一台 ZooKeeper集群中的机器,每台机器不能重 复,和myid一致。 ZXID:事务ID。ZXID是一个事务ID,用来 标识一次服务器状态的变更。在某一时刻, 集群中的每台机器的ZXID值不一定完全一 致,这和ZooKeeper服务器对于客户端“更 新请求”的处理逻辑有关。 Epoch:每个Leader任期的代号。没有 Leader时同一轮投票过程中的逻辑时钟值是 相同的。每投完一次票这个数据就会增加
第一次启动
(1)服务器1启 动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以上(3票),选举无法完成,服务器1状态保持为 LOOKING; (2)服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务器1发现服务器2的myid比自己目前投票推举的(服务器1) 大,更改选票为推举服务器2。此时服务器1票数0票,服务器2票数2票,没有半数以上结果,选举无法完成,服务器1,2状态保持LOOKING (3)服务器3启动,发起一次选举。此时服务器1和2都会更改选票为服务器3。此次投票结果:服务器1为0票,服务器2为0票,服务器3为3票。此时服 务器3的票数已经超过半数,服务器3当选Leader。服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING; (4)服务器4启动,发起一次选举。此时服务器1,2,3已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器3为3票,服务器4为 1票。此时服务器4服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING; (5)服务器5启动,同4一样当小弟。
非第一次启动
(1)当ZooKeeper集群中的一台服务器出现以下两种情况之一时,就会开始进入Leader选举: • 服务器初始化启动。 • 服务器运行期间无法和Leader保持连接。 (2)而当一台机器进入Leader选举流程时,当前集群也可能会处于以下两种状态: • 集群中本来就已经存在一个Leader。 对于第一种已经存在Leader的情况,机器试图去选举Leader时,会被告知当前服务器 的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连 接,并进行状态同步即可。 • 集群中确实不存在Leader。 假设ZooKeeper由5台服务器组成,SID分别为1、2、3、4、5,ZXID分别为8、8、 8、7、7,并且此时SID为3的服务器是Leader。某一时刻, 3和5服务器出现故障, 因此开始进行Leader选举。 SID为1、2、4的机器投票情况: (EPOCH,ZXID,SID ) (EPOCH,ZXID,SID ) (EPOCH,ZXID,SID ) (1,8,1) (1,8,2) (1,7,4) 选举Leader规则: ①EPOCH大的直接胜出 ②EPOCH相同,事务id大的胜出 ③事务id相同,服务器id大的胜出
zk集群启动停止脚本
客户端命令行操作
命令行语法
 
启动命令
启动/关闭 zk服务器 ./zkServer.sh start ./zkServer.sh stop 查看服务器状态 ./zkServer.sh status
znode节点数据信息
 (1)czxid:创建节点的事务 zxid 每次修改 ZooKeeper 状态都会产生一个 ZooKeeper 事务 ID。事务 ID 是 ZooKeeper 中所 有修改总的次序。每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2,那么 zxid1 在 zxid2 之 前发生。 (2)ctime:znode 被创建的毫秒数(从 1970 年开始) (3)mzxid:znode 最后更新的事务 zxid (4)mtime:znode 最后修改的毫秒数(从 1970 年开始) (5)pZxid:znode 最后更新的子节点 zxid (6)cversion:znode 子节点变化号,znode 子节点修改次数 (7)dataversion:znode 数据变化号 (8)aclVersion:znode 访问控制列表的变化号 (9)ephemeralOwner:如果是临时节点,这个是 znode 拥有者的 session id。如果不是 临时节点则是 0。 (10)dataLength:znode 的数据长度 (11)numChildren:znode 子节点数量
节点类型
持久节点
默认节点类型
临时节点
临时节点相较于持久节点来说就是它会随着客户端会话结束而被删除,通常可以用在一些特定的场景,如分布式锁释放、健康检查等。
持久顺序
临时顺序
概要
这两种放在一起介绍,他们相对于上面两种的特性就是ZK会自动在这两种节点之后增加一个数字的后缀,而路径 + 数字后缀是能保证唯一的,这数字后缀的应用场景可以实现诸如分布式队列,分布式公平锁等。
容器
容器节点是 3.5 以后新增的节点类型,只要在调用 create 方法时指定 CreateMode 为 CONTAINER 即可创建容器的节点类型,容器节点的表现形式和持久节点是一样的,但是区别是 ZK 服务端启动后,会有一个单独的线程去扫描,所有的容器节点,当发现容器节点的子节点数量为 0 时,会自动删除该节点,除此之外和持久节点没有区别,官方注释给出的使用场景是 Container nodes are special purpose nodes useful for recipes such as leader, lock, etc. 说可以用在 leader 或者锁的场景中。
持久TTL
持久顺序TTL
概要
这两种类型的节点重点是后面的 TTL,TTL 是 time to live 的缩写,指带有存活时间,简单来说就是当该节点下面没有子节点的话,超过了 TTL 指定时间后就会被自动删除,特性跟上面的容器节点很像,只是容器节点没有超时时间而已,但是 TTL 启用是需要额外的配置(这个之前也有提过)配置是 zookeeper.extendedTypesEnabled 需要配置成 true,否则的话创建 TTL 时会收到 Unimplemented 的报错。
监听器原理
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目 录节点增加删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数 据的任何改变都能快速的响应到监听了该节点的应用程序。
1、监听原理详解
 1)首先要有一个main()线程 2)在main线程中创建Zookeeper客户端,这时就会创建两个线 程,一个负责网络连接通信(connet),一个负责监听(listener)。 3)通过connect线程将注册的监听事件发送给Zookeeper。 4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。 5)Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。 6)listener线程内部调用了process()方法。
2、常见的监听
1)监听节点数据的变化 get path [watch] 2)监听子节点增减的变化 ls path [watch]
客户端API操作
IDEA环境搭建
创建Zookeeper客户端
创建子节点
获取子节点并监听节点变化
判断Znode是否存在
客户端向数据端写数据流程
写入请求直接发送给Leader节点

写入请求直接发送给Follower节点

4.服务器动态上下线监听案例
需求
需求分析
具体实现
测试
5.Zookeeper分布式锁案例
原生zookeeper实现分布式锁案例
Curator框架实现分布式锁案例
6.面试真题
选举机制
半数机制,超过半数的投票通过,即通过。 (1)第一次启动选举规则: 投票过半数时,服务器 id 大的胜出 (2)第二次启动选举规则: ①EPOCH 大的直接胜出 ②EPOCH 相同,事务 id 大的胜出 ③事务 id 相同,服务器 id 大的胜出
生产集群安装多少zk合适
安装奇数台。 生产经验: ⚫ 10 台服务器:3 台 zk; ⚫ 20 台服务器:5 台 zk; ⚫ 100 台服务器:11 台 zk; ⚫ 200 台服务器:11 台 zk 服务器台数多:好处,提高可靠性;坏处:提高通信延时
常用命令
ls、get、create、delete
算法
1.拜占庭将军问题
拜占庭将军问题是一个协议问题,拜占庭帝国军队的将军们必须全体一致的决定是否攻击某一支敌军。问题是这些将军在地理上是分隔开来的,并且将 军中存在叛徒。叛徒可以任意行动以达到以下目标:欺骗某些将军采取进攻行动;促成一个不是所有将军都同意的决定,如当将军们不希望进攻时促成进攻 行动;或者迷惑某些将军,使他们无法做出决定。如果叛徒达到了这些目的之一,则任何攻击行动的结果都是注定要失败的,只有完全达成一致的努力才能 获得胜利。
2.CAP
CAP理论概述
CAP理论告诉我们,一个分布式系统不可能同时满足以下三种 一致性(C:Consistency) 可用性(A:Available) 分区容错性(P:Partition Tolerance) 这三个基本需求,最多只能同时满足其中的两项,因为P是必须的,因此往往选择就在CP或者AP中。 1)一致性(C:Consistency) 在分布式环境中,一致性是指数据在多个副本之间是否能够保持数据一致的特性。在一致性的需求下,当一个系统在数 据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。 2)可用性(A:Available) 可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。 3)分区容错性(P:Partition Tolerance) 分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络 环境都发生了故障。
用CAP理论分析zookeeper
ZooKeeper保证的是CP (1)ZooKeeper不能保证每次服务请求的可用性。(注:在极端环境下,ZooKeeper可能会丢弃一些请求,消费者程序需要 重新请求才能获得结果)。所以说,ZooKeeper不能保证服务可用性。 (2)进行Leader选举时集群都是不可用。
3.一致性算法
Paxos算法
 Paxos算法:一种基于消息传递且具有高度容错特性的一致性算法 Paxos算法解决的问题:就是如何快速正确的在一个分布式系统中对某个数据值达成一致,并且保证不论发生任何异常,都不会破坏整个系统的一致性。
Paxos算法描述
在一个Paxos系统中,首先将所有节点划分为Proposer(提议者),Acceptor(接受者),和 Learner(学习者)。(注意:每个节点都可以身兼数职)。  一个完整的Paxos算法流程分为三个阶段: Prepare准备阶段 Proposer向多个Acceptor发出Propose请求Promise(承诺) Acceptor针对收到的Propose请求进行Promise(承诺) Accept接受阶段 Proposer收到多数Acceptor承诺的Promise后,向Acceptor发出Propose请求 Acceptor针对收到的Propose请求进行Accept处理 Learn学习阶段:Proposer将形成的决议发送给所有Learners
Paxos算法流程
 ( 1)Prepare: Proposer生成全局唯一且递增的Proposal ID,向所有Acceptor发送Propose请求,这里无需携带提案内容,只携 带Proposal ID即可。 2)Promise: Acceptor收到Propose请求后,做出“两个承诺,一个应答”。 不再接受Proposal ID小于等于(注意:这里是<= )当前请求的Propose请求。 不再接受Proposal ID小于(注意:这里是< )当前请求的Accept请求 不违背以前做出的承诺下,回复已经Accept过的提案中Proposal ID最大的那个提案的Value和Proposal ID,没有则 返回空值。 ( 3)Propose: Proposer收到多数Acceptor的Promise应答后,从应答中选择Proposal ID最大的提案的Value,作为本次要发起的 提 案。如果所有应答的提案Value均为空值,则可以自己随意决定提案Value。然后携带当前Proposal ID,向所有Acceptor发 送 Propose请求。 ( 4)Accept: Acceptor收到Propose请求后,在不违背自己之前做出的承诺下,接受并持久化当前Proposal ID和提案Value。 5)Learn: Proposer收到多数Acceptor的Accept后,决议形成,将形成的决议发送给所有Learner
Paxos缺点
Paxos 算法缺陷:在网络复杂的情况下,一个应用 Paxos 算法的分布式系统,可能很久 无法收敛,甚至陷入活锁(活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程)的情况
ZAB协议
Zab 借鉴了 Paxos 算法,是特别为 Zookeeper 设计的支持崩溃恢复的原子广播协议。基 于该协议,Zookeeper 设计为只有一台客户端(Leader)负责处理外部的写事务请求,然后 Leader 客户端将数据同步到其他 Follower 节点。即 Zookeeper 只有一个 Leader 可以发起提案
消息广播

崩溃恢复
异常假设
一旦Leader服务器出现崩溃或者由于网络原因导致Leader服务器失去了与过半 Follower的联系,那么就会进入崩溃恢复模式。  1)假设两种服务器异常情况: (1)假设一个事务在Leader提出之后,Leader挂了。 (2)一个事务在Leader上提交了,并且过半的Follower都响应Ack了,但是Leader在Commit消息发出之前挂了。 2)Zab协议崩溃恢复要求满足以下两个要求: (1)确保已经被Leader提交的提案Proposal,必须最终被所有的Follower服务器提交。 (已经产生的提案,Follower必须执行) (2)确保丢弃已经被Leader提出的,但是没有被提交的Proposal。(丢弃胎死腹中的提案)
Leader选举
 Leader选举:根据上述要求,Zab协议需要保证选举出来的Leader需要满足以下条件: (1)新选举出来的Leader不能包含未提交的Proposal。即新Leader必须都是已经提交了Proposal的Follower服务器节点。 (2)新选举的Leader节点中含有最大的zxid。这样做的好处是可以避免Leader服务器检查Proposal的提交和丢弃工作。
数据恢复
 Zab如何数据同步: (1)完成Leader选举后,在正式开始工作之前(接收事务请求,然后提出新的Proposal),Leader服务器会首先确认事务日 志中的所有的Proposal 是否已经被集群中过半的服务器Commit。 (2)Leader服务器需要确保所有的Follower服务器能够接收到每一条事务的Proposal,并且能将所有已经提交的事务Proposal 应用到内存数据中。等到Follower将所有尚未同步的事务Proposal都从Leader服务器上同步过,并且应用到内存数据中以后, Leader才会把该Follower加入到真正可用的Follower列表中。
源码
1.辅助源码
持久化源码
序列化源码
2.zk服务端初始化源码解析
zk服务端启动脚本分析
zk服务端启动入口
参数解析zoo.cfg和myid
过期快照删除
初始化通信组件
3.zk服务端加载数据解析
启动数据回复快照数据
启动数据回复编辑日志
4.zk选举源码解析
选举准备
选举执行
5.Follower和Leader状态同步源码
6.服务端Leader启动
7.服务端Follower启动
8.客户端启动
创建ZookeeperMain
初始化监听器
解析链接地址
创建通信
执行run