Zookeeper通过ZAB保证分布式事务的最终一致性。
ZAB全称Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息广播协议)
ZAB是一种专门为Zookeeper设计的一种支持 崩溃恢复 的 原子广播协议 ,是Zookeeper保证数据一致性的核心算法。ZAB借鉴了Paxos算法,但它不是通用的一致性算法,是特别为Zookeeper设计的。
基于ZAB协议,Zookeeper实现了⼀种主备模式的系统架构来保持集群中各副本之间的数据的⼀致性,表现形式就是使⽤⼀个单⼀的主进程(Leader服务器)来接收并处理客户端的所有事务请求(写请求),并采⽤ZAB的原⼦⼴播协议,将服务器数据的状态变更为事务 Proposal的形式⼴播到所有的Follower进程中。
问题提出主从架构下,leader 崩溃,数据一致性怎么保证?
选举 leader 的时候,整个集群无法处理写请求的,如何快速进行 leader 选举?
ZAB过程ZAB协议的核⼼是 定义了对于那些会改变Zookeeper服务器数据状态的事务请求的处理⽅式
所有事务必须由一个 全局唯一的服务器来协调处理 ,这样的服务器被称为Leader服务器,余下的服务器则称为Follower服务器
Leader服务器负责将一个客户端事务请求转化为一个事务Proposal(提案),并将该Proposal分发给集群中所有的Follower服务器
Leader服务器等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,Leader就会向所有的Follower服务器发送Commit消息,要求将前一个Proposal进行提交。
ZAB协议内容简介ZAB协议包括两种基本的模式: 崩溃恢复 和 消息广播
消息广播当集群中有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就可以进入 消息广播模式 。
当一台遵守ZAB协议的服务器启动后加入到集群中,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么加入的服务器会自觉的进入 数据恢复模式: 找到Leader 所在的服务器,并与其进⾏数据同步,数据同步完成后参与到消息⼴播流程中。
ZAB协议的消息广播使用原子广播协议, 类似一个二阶段提交的过程 ,但又有所不同。
二阶段提交中,需要所有参与者反馈ACK后再发送Commit请求。要求所有参与者要么成功,要么失败。这样会产生严重的阻塞问题
ZAB协议中,Leader等待半数以上的Follower成功反馈ACK即可,不需要收到全部的Follower反馈ACK。
消息广播过程:
客户端发起写请求
Leader将客户端请求信息转化为事务Proposal,同时为每个Proposal分配一个事务ID(Zxid)
Leader为每个Follower单独分配一个FIFO的队列,将需要广播的Proposal依次放入到队列中
Follower接收到Proposal后,首先将其以事务日志的方式写入到本地磁盘中,写入成功后给Leader反馈一个ACK响应
Leader接收到半数以上Follower的ACK响应后,即认为消息发送成功,可以发送Commit消息
Leader向所有Follower广播Commit消息,同时自身也会完成事务提交。Follower接收到Commit消息后也会完成事务的提交
崩溃恢复在整个服务框架启动过程中,如果Leader服务器出现网络中断、崩溃退出或重启等异常情况,ZAB协议就会进入崩溃恢复模式。同时选举出新的Leader服务器。
当选举产生了新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步(数据同步)之后,ZAB协议会退出恢复模式。
在ZAB协议中,为了保证程序的正确运⾏,整个恢复过程结束后需要选举出⼀个新的Leader 服务器。
Leader选举算法不仅仅需要让Leader⾃身知道已经被选举为Leader,同时还需要让集群中的所有其他机器也能够快速地感知到选举产⽣出来的新Leader服务器。
ZAB保证数据一致性ZAB协议规定了 如果⼀个事务Proposal在⼀台机器上被处理成功,那么应该在所有的机器上都被处理成功,哪怕机器出现故障崩溃。 针对这些情况ZAB协议需要保证以下条件:
已经在Leader服务器上提交的事务最终被所有服务器都提交。
假设⼀个事务在 Leader 服务器上被提交了,并且已经得到过半 Folower 服务器的Ack反馈,但是在它 将Commit消息发送给所有Follower机器之前,Leader服务器挂了
丢弃只在Leader服务器上被提出(未提交)的事务。