Zookeeper通过ZAB保障分布式事务的最终一致性。
ZAB全称Zookeeper Atomic Broadcast(ZAB,Zookeeper原子音讯播送协定)
1.ZAB是一种专门为Zookeeper设计的一种反对 解体复原 的 原子播送协定 ,是Zookeeper保证数据一致性的外围算法。ZAB借鉴了Paxos算法,但它不是通用的一致性算法,是特地为Zookeeper设计的。
2.基于ZAB协定,Zookeeper实现了⼀种主备模式的零碎架构来放弃集群中各正本之间的数据的⼀致性,表现形式就是使⽤⼀个单⼀的主过程(Leader服务器)来接管并解决客户端的所有事务申请(写申请),并采⽤ZAB的原⼦⼴播协定,将服务器数据的状态变更为事务 Proposal的模式⼴播到所有的Follower过程中。
问题提出
- 主从架构下,leader 解体,数据一致性怎么保障?
- 选举 leader 的时候,整个集群无奈解决写申请的,如何疾速进行 leader 选举?
ZAB过程
ZAB协定的核⼼是 定义了对于那些会扭转Zookeeper服务器数据状态的事务申请的解决⽅式
所有事务必须由一个 全局惟一的服务器来协调解决 ,这样的服务器被称为Leader服务器,余下的服务器则称为Follower服务器
1.Leader服务器负责将一个客户端事务申请转化为一个事务Proposal(提案),并将该Proposal分发给集群中所有的Follower服务器
2.Leader服务器期待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,Leader就会向所有的Follower服务器发送Commit音讯,要求将前一个Proposal进行提交。
ZAB协定内容简介
ZAB协定包含两种根本的模式: 解体复原 和 音讯播送
音讯播送
当集群中有过半的Follower服务器实现了和Leader服务器的状态同步,那么整个服务框架就能够进入 音讯播送模式 。
当一台恪守ZAB协定的服务器启动后退出到集群中,如果此时集群中曾经存在一个Leader服务器在负责进行音讯播送,那么退出的服务器会盲目的进入 数据恢复模式:找到Leader 所在的服务器,并与其进⾏数据同步,数据同步实现后参加到音讯⼴播流程中。
ZAB协定的音讯播送应用原子播送协定, 相似一个二阶段提交的过程 ,但又有所不同。
1.二阶段提交中,须要所有参与者反馈ACK后再发送Commit申请。要求所有参与者要么胜利,要么失败。这样会产生重大的阻塞问题;
2.ZAB协定中,Leader期待半数以上的Follower胜利反馈ACK即可,不须要收到全副的Follower反馈ACK。
音讯播送过程:
1.客户端发动写申请
2.Leader将客户端申请信息转化为事务Proposal,同时为每个Proposal调配一个事务ID(Zxid)
3.Leader为每个Follower独自调配一个FIFO的队列,将须要播送的Proposal顺次放入到队列中
4.Follower接管到Proposal后,首先将其以事务日志的形式写入到本地磁盘中,写入胜利后给Leader反馈一个ACK响应
5.Leader接管到半数以上Follower的ACK响应后,即认为音讯发送胜利,能够发送Commit音讯
6.Leader向所有Follower播送Commit音讯,同时本身也会实现事务提交。Follower接管到Commit音讯后也会实现事务的提交
解体复原
在整个服务框架启动过程中,如果Leader服务器呈现网络中断、解体退出或重启等异常情况,ZAB协定就会进入解体恢复模式。同时选举出新的Leader服务器。
当选举产生了新的Leader服务器,同时集群中曾经有过半的机器与该Leader服务器实现了状态同步(数据同步)之后,ZAB协定会退出恢复模式。
1.在ZAB协定中,为了保障程序的正确运⾏,整个复原过程完结后须要选举出⼀个新的Leader 服务器。
2.Leader选举算法不仅仅须要让Leader⾃身晓得曾经被选举为Leader,同时还须要让集群中的所有其余机器也可能疾速地感知到选举产⽣进去的新Leader服务器。
ZAB保证数据一致性
ZAB协定规定了 如果⼀个事务Proposal在⼀台机器上被解决胜利,那么应该在所有的机器上都被解决胜利,哪怕机器呈现故障解体。 针对这些状况ZAB协定须要保障以下条件:
- 曾经在Leader服务器上提交的事务最终被所有服务器都提交。
假如⼀个事务在 Leader 服务器上被提交了,并且曾经失去过半 Folower 服务器的Ack反馈,然而在它 将Commit音讯发送给所有Follower机器之前,Leader服务器挂了 - 抛弃只在Leader服务器上被提出(未提交)的事务。
假如初始的 Leader 服务器 Server1 在提出了⼀个事务Proposal3 之后就解体退出 了,从⽽导致集群中的其余服务器都没有收到这个事务Proposal3。于是,当 Server1 恢复过来再次加 ⼊到集群中的时候,ZAB 协定须要确保抛弃Proposal3这个事务。
综上所述,ZAB的选举进去的Leader必须满足以下条件:
可能确保提交曾经被 Leader 提交的事务 Proposal,同时抛弃曾经被跳过的事务 Proposal。即:
1.新选举进去的 Leader 不能蕴含未提交的 Proposal。
2.新选举的 Leader 节点中含有最大的 zxid 。
ZAB如何数据同步
所有失常运行的服务器要么成为Leader,要么成为Follower并和Leader放弃同步。
1.实现Leader选举(新的 Leader 具备最高的zxid)之后,在正式开始⼯作(接管客户端申请)之前,Leader服务器会⾸先确认事务⽇志中的所有Proposal是否都曾经被集群中过半的机器提交了,即 是否实现数据同步 。
2.Leader服务器须要确保所有的Follower服务器可能接管到每⼀条事务Proposal,并且可能正确地将所有曾经提交了的事务Proposal应⽤到内存数据中。等到 Follower服务器将所有其尚未同步的事务 Proposal 都从 Leader 服务器上同步过去并胜利应⽤到本地数据库中后,Leader服务器就会将该Follower服务器加⼊到真正的可⽤Follower列表中,并开始之后的其余流程。
ZAB运行时状态#
ZAB协定设计中,每个过程都有可能处于如下三种状态之一:
- LOOKING:Leader选举状态,正在寻找Leader
- FOLLOWING:以后节点是Follower。与Leader服务器放弃同步状态
- LEADING:以后节点是Leader,作为主过程领导状态。
ZAB状态的切换
启动时的状态转换
1.所有过程的初始状态都是LOOKING状态,此时不存在Leader。
2.接下来,过程会试图选举进去一个新的Leader,Leader切换为LEADING状态,其它过程发现曾经选举出新的Leader,那么它就会切换到FOLLOWING状态,并开始与Leader放弃同步。
3.处于FOLLOWING状态的过程称为Follower,LEADING状态的过程称为Leader。
4.当Leader解体或者放弃领导位置时,其余的Follower过程就会切换到LOOKING状态开始新一轮的Leader选举。
运行过程中的状态转换
一个Follower只能和一个Leader放弃同步,Leader过程和所有的Follower过程之间通过心跳监测机制来感知彼此的状况。
1.若Leader可能在超时工夫内失常的收到心跳检测,那么Follower就会始终与该Leader放弃连贯。
2.如果在指定工夫内Leader无奈从过半的Follower过程那里接管到心跳检测,或者TCP连贯断开,那么Leader会放弃以后周期的领导,并转换为LOOKING状态;其余的Follower也会抉择放弃这个Leader,同时转换为LOOKING状态,之后会进行新一轮的Leader选举
ZAB的四个阶段
选举阶段(Leader Election)
节点在一开始都处于选举阶段,只有有一个节点超过半数阶段的票数,它就能够入选准Leader,只有达到第三个阶段(同步阶段),这个准Leader才会成为真正的Leader。
这一阶段的目标就是为了选出一个准Leader,而后进入下一阶段。
发现阶段
在这个阶段中,Followers和上一轮选举出的准Leader进行通信,同步Followers最近承受的事务Proposal。这个阶段次要目标是发现以后大多数节点承受的最新提议,并且准Leader生成新的epoch,让Followers承受,更新它们的acceptedEpoch。
一个Follower只会连贯一个Leader,如果有一个节点F认为另一个Follower P是Leader,F在尝试连贯P时会被回绝,F被回绝后,就会进入选举阶段。
同步阶段
同步阶段次要是利用 Leader 前一阶段取得的最新 Proposal 历史,同步集群中所有的正本。
只有当 quorum(超过半数的节点) 都同步实现,准 Leader 才会成为真正的 Leader。Follower 只会接管 zxid 比本人 lastZxid 大的 Proposal。
播送阶段
到了这个阶段,Zookeeper 集群能力正式对外提供事务服务,并且 Leader 能够进行音讯播送。同时,如果有新的节点退出,还须要对新节点进行同步。须要留神的是,Zab 提交事务并不像 2PC 一样须要全副 Follower 都 Ack,只须要失去 quorum(超过半数的节点)的Ack 就能够。
ZAB协定实现
Java 版本的ZAB协定的实现跟下面的定义略有不同,选举阶段应用的是 Fast Leader Election(FLE),它蕴含了步骤2的发现职责。因为FLE会选举领有最新提议的历史节点作为 Leader,这样就省去了发现最新提议的步骤。
理论的实现将 发现和同步阶段合并为 Recovery Phase(复原阶段) ,所以,Zab 的实现实际上有三个阶段。
疾速选举(Fast Leader Election)
后面提到的 FLE 会选举领有最新Proposal history (lastZxid最大)的节点作为 Leader,这样就省去了发现最新提议的步骤。 这是基于领有最新提议的节点也领有最新的提交记录
成为Leader的条件:
1.选epoch最大的
2.epoch相等,选zxid最大的
3.epoch和zxid都相等,选server_id最大的(zoo.cfg 中配置的 myid)
节点在选举开始时,都默认投票给本人,当接管其余节点的选票时,会依据下面的 Leader条件 判断并且更改本人的选票,而后从新发送选票给其余节点。当有一个节点的得票超过半数,该节点会设置本人的状态为 Leading ,其余节点会设置本人的状态为 Following。
复原阶段(Recovery Phase)
这一阶段 Follower 发送他们的 lastZxid 给 Leader,Leader 依据 lastZxid 决定如何同步数据。这里的实现跟后面的 阶段 3 有所不同:Follower 收到 TRUNC 指令会终止 L.lastCommitedZxid 之后的 Proposal ,收到 DIFF 指令会接管新的 Proposal。
history.lastCommittedZxid:最近被提交的提议的 zxid history.oldThreshold:被认为曾经太旧的已提交提议的 zxid
播送阶段(Broadcast Phase)
参考 4.1 [ZAB协定内容#音讯播送]
ZAB与Paxos的分割和区别
分割
1.都存在一个相似Leader过程的角色,由其负责协调多个Follower过程的运行
2.Leader过程都会期待超过半数的Follower作出正确的反馈后,才会将一个提议进行提交(过半准则)
3.在ZAB中,每个Proposal中都蕴含了一个epoch值,用来代表以后Leader周期,在Paxos中同样存在这样的一个示意,名字为 Ballot。
区别
1.Paxos算法中,新选举产生的主过程会进行两个阶段的工作;第一阶段称为读阶段:新的主过程和其余过程通信来收集主过程提出的提议,并将它们提交。第二阶段称为写阶段:以后主过程开始提出本人的提议。
2.ZAB协定在Paxos根底上增加了同步阶段,此时,新的Leader会确保存在过半的Follower曾经提交了之前Leader周期中的所有事物Proposal。这一同步阶段的引入,可能无效保障,Leader在新的周期中提出事务Proposal之前,所有的过程都曾经实现了对之前所有事务Proposal的提交。
总的来说,ZAB协定和Paxos算法的本质区别在于两者的设计目标不一样:ZAB协定次要用于构建一个高可用的分布式数据主备零碎,而Paxos算法则用于构建一个分布式的一致性状态机零碎。
总结
问题解答:
1.主从架构下,leader 解体,数据一致性怎么保障?
leader 解体之后,集群会选出新的 leader,而后就会进入复原阶段,新的 leader 具备所有曾经提交的提议,因而它会保障让 followers 同步已提交的提议,抛弃未提交的提议(以 leader 的记录为准),这就保障了整个集群的数据一致性。
2.选举 leader 的时候,整个集群无奈解决写申请的,如何疾速进行 leader 选举?
这是通过 Fast Leader Election 实现的,leader 的选举只须要超过半数的节点投票即可,这样不须要期待所有节点的选票,可能尽早选出 leader。
起源 | https://urlify.cn/RRziQf
欢送关注我的微信公众号「码农解围」,分享Python、Java、大数据、机器学习、人工智能等技术,关注码农技术晋升•职场解围•思维跃迁,20万+码农成长充电第一站,陪有幻想的你一起成长