Zookeeper集群一致性协议—— ZAB算法

ZAB协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性。Zookeeper就是根据zab协议建立了主备模型完成集群的数据同步(保证数据的一致性),在 Zookeeper集群部署 中介绍了Zookeeper集群的各种角色,如Leader、Follower,并介绍了各个的作用。
在这里插入图片描述


Zookeeper中所说的主备架构模型指的是,在Zookeeper集群中,只有一台Leader(主节点)负责处理外部客户端的事务请求(写操作),Leader节点负责将客户端的写操作数据同步到所有的Follower节点中。
在这里插入图片描述

zab协议核心是在整个Zookeeper集群中只有一个节点既Leader 将所有客户端的写操作转化为事务(提议Proposal)。Leader节点再数据写完之后,将向所有的Follower 节点发送数据广播请求(数据复制),等所有的Follower 节点的反馈,在zab协议中,只要超过半数follower 节点反馈OK, Leader节点会向所有Follower 服务器发送commit消息,即将Leader 节点上的数据同步到Follower 节点之上。
在这里插入图片描述

消息广播

我们发现,整个流程其实和Paxos协议其实大同小异,其中也是分为两阶段,其实我们可以把zab协议看做是Paxos算法的实现。在zab协议中同样也是只要求超过半数follower 节点反馈OK 即可,这就是ZAB协议中的一种模式——消息广播 ,其具体步骤如下:

  1. 客户端发起一个写操作请求

  2. Leader 服务器将客户端的request 请求转化为事务提案(Proposql),同时为每个提案(Proposql)分配一个全局唯一的64位自增ID,即ZXID,通过ZXID的大小比较即可实现因果有序这一特性。

  3. Leader 服务器与每个Follower 之间都有一个先进先出的队列(通过 TCP 协议来实现,以此实现了全局有序这一特性),Leader将将带有ZXID的消息作为一个提案(Proposal)发送到该队列,以通知所有的Follower

  4. Follower 机器从队列中取出消息进行处理,处理完毕后(写入本地事物日志中),向Leader 服务器发送ACK确认

  5. Leader 服务器收到半数以上的Follower 的ACK后,即认为可以发送commit

  6. Leader 向所有的Follower 服务器发送commit消息
    在这里插入图片描述

上述并没有像一致性协议—— Paxos算法 中一样拥有多个提议者 (Proposer),在一致性协议—— Paxos算法最后也提到过,就是为了保证其算法的活性,避免陷入死循环。


另外为了进一步防止阻塞,Leader 服务器与每个Follower 之间都有一个单独的队列进行收发消息,使用队列消息可以做到异步解耦。Leader 和Follower 之间只要往队列中发送了消息即可。如果使用同步方式容易引起阻塞。性能上要下降很多。




崩溃恢复

除了上述我们所说的消息恢复外,ZAB协议中另一个重要的部分就是崩溃恢复,Zookeeper集群中为保证任何所有进程能够有序的顺序执行,只能是Leader 服务器接受写请求,即使是Follower 服务器接受到客户端的请求,也会转发到leader服务器进行处理。


但是如果Leader 服务器发生崩溃(重启是一种特殊的奔溃,这时候也没Leader),则zab协议要求Zookeeper集群进行崩溃恢复和Leader服务器选举(在这期间,节点暂不可用,节点状态为LOOKING),如现在有5台服务器,Server1是Leader服务器,这时Server1和Server发现了故障,崩溃了,这时崩溃恢复和Leader服务器选举其过程如下:
在这里插入图片描述

  1. 每个Server会发出一个投票,第一次都是投自己。投票信息:(myid,ZXID)
  2. 收集来自各个服务器的投票
  3. 处理投票并重新投票,处理逻辑:优先比较ZXID,然后比较myid
  4. 统计投票,只要超过半数的机器接收到同样的投票信息,就可以确定Leader
  5. 改变服务器状态

这里我们来看一下,如何要优先比较ZXID,选择ZXID较大的节点作为Leader呢?因为在ZAB协议崩溃恢复要求满足如下2个要求:

  1. 确保已经被Leader 提交的提案(Proposal) 必须最终被所有的Follower服务器提交
  2. 确保丢弃已经被Leader 出的但是没有被提交的提案(Proposal)

所以新选举的Leader 节点中含有最高的ZXID,可以保证Leader 服务器可以拿到最新的数据,这样做的好处就是可以避免了Leader服务器检查提案(Proposal) 的提交和丢弃工作。

就是指在之前的Leader节点崩溃了之后,ZXID最大的节点肯定是接收到了前Leader节点最新的命令,如果有数据ZXID最大的节点已确定提交,别的节点没有接到指令,正在等待,那么别的节点就应该进行提交;如果ZXID最大的节点有数据在等待提交,这时说明之前没有任何节点接收到commit指令,无法判断其是否应该进行提交,这时应当进行丢弃保证数据的一致性。


其中ZXID就是事务ID,是系统维护的64位自增ID,在一致性协议—— Paxos算法中就是指提议者 (Proposer)提出的提案 (Proposal) 的编号ID,而myid就是我们在Zookeeper集群部署 中进行配置的myid文件中的值。




Zookeeper集群的生命周期

在了解了ZAB协议中的消息广播崩溃恢复,我们来看一下下图中的Zookeeper集群的生命周期,如下:
在这里插入图片描述


1、崩溃恢复

我们结合Zookeeper集群部署 中我们动手部署Zookeeper的实例可以来进行了解,首先在配置完Zookeeper的相关配置之后,我们启动了第一台机器时,发现Zookeeper集群并未能够成功运行(未达到集群的大多数),因为在新启动的时候,Zookeeper集群需要达到半数以上,从而才可以进行选举,选好新的 Leader之后,集群就可以进行正常的运行了

2、正常运行

我们在Zookeeper集群部署 中启动了第二台机器后,Zookeeper集群就可以正常运行了,因为这是已经达到了半数以上(除去配置的Observer机器),所以我们就可以进行选举Leader了,这时集群是可以正常进行运行的

3、崩溃恢复

这个崩溃恢复主要是指在Zookeeper集群正常运行期间,Leader节点崩溃的时候,这时我们就需要选举新的Leader,选好新的Leader 之后会进行一次数据同步操作,整个过程就是奔溃恢复

4、数据同步

这个数据同步的过程,是指在Zookeeper集群正常运行过程中,有节点崩溃了,但是过了一段时间后,它有正常连接到集群之中了,这时,它就需要进行数据同步,来保证其数据的一致性。

发布了286 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/newbie0107/article/details/105022940