一、什么是Zab协议
ZAB协议 的全称是 Zookeeper Atomic Broadcast (Zookeeper原子广播)。
ZAB 协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的一致性协议。基于该协议,ZooKeeper 实现了一种主从模式的系统架构来保持集群中各个副本之间的数据一致性。
话说在分布式系统中一般使用主从系统架构模型,指的是一台leader服务器负责外部客户端的写请求。然后其他的都是follower服务器。leader服务器将客户端的写操作数据同步到所有的follower节点中。
就这样,客户端发送来的写请求,全部给Leader,然后leader再转给Follower。这时候需要解决两个问题:
(1)leader服务器是如何把数据更新到所有的Follower的。
(2)Leader服务器突然间失效了,怎么办?
因此ZAB协议为了解决上面两个问题,设计了两种模式:
(1)消息广播模式:把数据更新到所有的Follower
(2)崩溃恢复模式:Leader发生崩溃时,如何恢复
当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,Zab协议就会 进入崩溃恢复模式,发起一轮Leader选举并实现数据同步。
当选举产生了新的 Leader,同时集群中有过半的机器与该 Leader 服务器完成了状态同步(即数据同步)之后,Zab协议就会退出崩溃恢复模式,进入消息广播模式。
这时,如果有一台遵守Zab协议的服务器加入集群,因为此时集群中已经存在一个Leader服务器在广播消息,那么该新加入的服务器自动进入恢复模式:找到Leader服务器,并且完成数据同步。同步完成后,作为新的Follower一起参与到消息广播流程中。
下面我们来从这2个问题来看看是如何解决的
在zookeeper集群中,数据副本的传递策略就是采用消息广播模式。
在zookeeper使用的事务,与二段提交相似,但是却又不同。由Leader服务器负责将一个客户端事务请求,转换成一个事务Proposal 生成一个全局唯一的事务id,并将该 Proposal 分发给集群中所有的 Follower 服务器,Leader服务器需要等待所有Follower服务器的反馈(Ack请求),在Zab协议中,只要超过半数的Follower服务器进行了正确的反馈后(也就是收到半数以上的Follower的Ack请求),那么 Leader 就会再次向所有的 Follower服务器发送 Commit 消息,要求其将上一个 事务proposal 进行提交。而且在协议当中规定每一个消息的严格的顺序关系,所每一个proposal按照其zxid的先后顺序进行排序和处理。
1)客户端发起一个写操作请求。
2)Leader 服务器将客户端的请求转化为事务 Proposal 提案,同时为每个 Proposal 分配一个全局的ID,即zxid。
3)Leader 服务器为每个 Follower 服务器分配一个单独的队列,然后将需要广播的 Proposal 依次放到队列中取,并且根据 FIFO 策略进行消息发送。
4)Follower 接收到 Proposal 后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向 Leader 反馈一个 Ack 响应消息。
5)Leader 接收到超过半数以上 Follower 的 Ack 响应消息后,即认为消息发送成功,可以发送 commit 消息。
6)Leader 向所有 Follower 广播 commit 消息,同时自身也会完成事务提交。Follower 接收到 commit 消息后,会将上一条事务提交。
一旦 Leader 服务器出现崩溃或者由于网络原因导致 Leader 服务器失去了与过半 Follower 的联系,那么就会进入崩溃恢复模式。
在 Zab 协议中,为了保证程序的正确运行,整个恢复过程结束后需要选举出一个新的 Leader 服务器。因此 Zab 协议需要一个高效且可靠的 Leader 选举算法,从而确保能够快速选举出新的 Leader 。
Leader 选举算法不仅仅需要让 Leader 自己知道自己已经被选举为 Leader ,同时还需要让集群中的所有其他机器也能够快速感知到选举产生的新 Leader 服务器。
崩溃恢复主要包括两部分:Leader选举 和 数据恢复
Leader选举
在集群启动过程中的 Leader 选举过程(算法)与 Leader 断连后的 Leader 选举过程稍微 有一些区别,基本相同。
在Leader 断连后断链的流程中,Leader 挂后,余下的非 Observer 服务器都会将自己的服务器状态由 FOLLOWING 变更为 LOOKING,然后开始进入 Leader 选举过程。
其中选票pk规则如下:
下面是选举流程:
数据恢复
leader选举出来了,下面就要进行数据恢复了
主要分为3步
在同步阶段要考虑下,leader到底是如何挂掉的了其中有2种情况
1.Leader 在收到 Ack 并提交了自己,同时发送了部分 commit 出去之后崩溃
针对这种情况ZAP定义了:已经被处理的消息不能丢失
因为每次提交的事务都有一个zxid(全局唯一,递增),因此我们只需要找出所有机器内zxid最大的事务(既该事务是最后一个被提交的事务)并且把存放该zxid的机器选举为leader即可,还可以省去 Leader 服务器检查事务的提交和丢弃工作的这一步操作。
2.当leader收到事务请求,并且还没有发起事务投票之前,leader宕机。
针对这种情况ZAP定义了:已经被丢弃的消息不能再次出现
之前宕机的leader节点重新启动之后若再次被选为Leader,要把之前没有commit的事务重新commit,而当前的epoch大于该事务的epoch所以事务会被丢弃而不会被重新加载。也就是只有当事务zxid的epoch和当前的epoch相同时,事务才会被提交。
参考链接!https://www.jianshu.com/p/b82aaed5389c
https://www.jianshu.com/p/2bceacd60b8a
https://baijiahao.baidu.com/s?id=1666465070459184658&wfr=spider&for=pc