暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

漫谈ZAB协议——消息广播

糖爸的架构师之路 2021-06-24
881

写在前面

最近这段时间非常的忙,参与的项目排期越来越紧,加上春节假期之后上班的不适,导致一直在不工作的时候也不想碰电脑。不过这几天突然发现自己的笔记本电脑电池鼓包的现象越来越严重,于是又对之前一直心心念的iMac 5K有了冲动,但是想一想5K + Dell2720QM,又翻翻自己的支付宝,哎,只能起床继续努力啦。
在前两篇和ZAB协议相关的文章漫谈ZAB协议——选举漫谈ZAB协议——数据恢复与同步中,我们详细的介绍了ZAB协议中两个重要组成部分的其中一个——崩溃恢复。其实严格意义上来讲,选举和数据恢复都属于崩溃恢复阶段的内容。那在正常情况下,在Zookeeper集群中,各个节点是如何保持数据一致性的呢?ZAB协议中的二阶段提交和二阶段提交协议,有什么异同点呢?带着这些疑问,我们来相信看一下ZAB协议中的另一个重要组成部分——消息广播

一致性协议——2PC
要解释清楚消息广播的主要流程,就不得不提到消息一致性协议。在对一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议。
为了解决分布式一致性问题,涌现出了一大批经典的一致性协议和算法,其中最著名的就是二阶段提交协议、三阶段提交协议和 Paxos 算法ZAB协议的消息广播就是在二阶段提交协议的基础之上进行了一定程度的定制和修改。所以要搞清楚消息广播的流程,我们就需要先了解一下二阶段提交协议的相关内容。


定义

2PC,是 Two-Phase Commit 的缩写,即二阶段提交,是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和一致性而设计的一种算法。通常,二阶段提交协议也被认为是一种一致性协议,用来保证分布式系统数据的一致性。目前,绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务处理的,利用该协议能够非常方便地完成所有分布式事务参与者的协调,统一决定事务的提交或回滚,从而能够有效地保证分布式数据一致性,因此二阶段提交协议被广泛地应用在许多分布式系统中。


协议说明
顾名思义,二阶段提交协议是将事务的提交过程分成了两个阶段来进行处理,其执行流程如下。


提交事务请求(投票阶段)

  1. 事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。
  2. 执行事务:各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中。
  3. 各参与者向协调者反馈事务询问的响应
  • 如果参与者成功执行了事务操作,那么就反馈给协调者 Yes 响应,表示事务可以执行。
  • 如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不可以执行。


执行事务提交

假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务提交。

  1. 发送提交请求:协调者向所有参与者节点发出Commit 请求。
  2. 务提交:参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。
  3. 反馈事务提交结果:参与者在完成事务提交之后,向协调者发送 ACK 消息。
  4. 完成事务:协调者接收到所有参与者反馈的ACK 消息后,完成事务。


中断事务

        假如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务
  1. 发送回滚请求:协调者向所有参与者节点发出 Rollback 请求。
  2. 事务回滚:参与者接收到Rollback 请求后,会利用其在阶段一中记录的 Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。
  3. 反馈事务回滚结果:参与者在完成事务回滚之后,向协调者发送 Ack 消息。
  4. 中断事务:协调者接收到所有参与者反馈的Ack消息后,完成事务中断。

以上就是二阶段提交过程中,前后两个阶段分别进行的处理逻辑。简单地讲,二阶段提交将一个事务的处理过程分为了投票执行两个阶段,其核心是对每个事务都采用先尝试后提交的处理方式,因此也可以将二阶段提交看作一个强一致性的算法。


优缺点

  • 优点:原理简单,实现方便。

  • 缺点:

同步阻塞

二阶段提交协议存在的最明显也是最大的一个问题就是同步阻塞,这会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。


单点问题
协调者的角色在整个二阶段提交协议中起到了非常重要的作用。一旦协调者出现问题,那么整个二阶段提交流程将无法运转,更为严重的是,如果协调者是在阶段二中出现问题的话,那么其他参与者将会一直处于锁定事务资源的状态中,而无法继续完成事务操作。


数据不一致

在二阶段提交协议的阶段二,即执行事务提交的时候,当协调者向所有的参与者发送Commit请求之后,发生了局部网络异常或者是协调者在尚未发送完Commit 请求之前自身发生了崩溃,导致最终只有部分参与者收到了Commit 请求。于是,这部分收到了Commit 请求的参与者就会进行事务的提交,而其他没有收到Commit 请求的参与者则无法进行事务提交,于是整个分布式系统便出现了数据不一致性现象。


ZAB协议——消息广播
有了上面对2PC协议的介绍,我们就可以很轻松的理解ZAB协议中的消息广播流程

具体步骤

  1. 客户端发起一个写操作请求。
  2. Leader 服务器将客户端的请求转化为事务 Proposal 提案,同时为每个 Proposal 分配一个全局的ID,即zxid。
  3. Leader 服务器为每个 Follower 服务器分配一个单独的队列,然后将需要广播的 Proposal 依次放到队列中,并且根据 FIFO 策略进行消息分发。这样做可以做到异步解耦Leader 和 Follower 之间只需要往队列中发消息即可。如果使用同步的方式会引起阻塞,性能要下降很多。

  4. Follower 接收到 Proposal 后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向 Leader 反馈一个 Ack 响应消息。
  5. Leader 接收到超过半数以上 Follower 的 Ack 响应消息后,即认为消息发送成功,可以发送 commit 消息。
  6. Leader 向所有 Follower 广播 commit 消息,同时自身也会完成事务提交。Follower 接收到 commit 消息后,会将上一条事务提交。

       

2PC与ZAB协议的异同

ZAB协议中的二阶段提交过程和上面提到过的二阶段提交协议的内容是有一些不同之处的。在 ZAB 协议二阶段提交过程中,移除了中断逻辑,所有的 Follower 服务器要么正常反馈 Leader 提出的事务 Proposal,要么就抛弃 Leader 服务器。同时,ZAB协议将二阶段提交中的中断逻辑移除意味着我们可以在过半的 Follower 服务器已经反馈 ACK 之后就开始提交事务 Proposal了,而不需要等待集群中所有的 Follower 服务器都反馈响应。当然,在这种简化了的二阶段提交模型下,是无法处理 Leader 服务器崩溃退出而带来的数据不一致问题的,因此在ZAB协议中添加了另一个模式,即采用崩溃恢复模式来解决这个问题。这也是ZAB协议通过 CAP/BASE 实现最终一致性的一个体现。


ZAB协议总结

通过几篇对ZAB协议的介绍,我们知道ZAB协议最核心的内容就是三个阶段,即发现阶段、同步阶段、广播阶段。所以我们用更精炼的语言来总结下每个阶段都做了哪些事情,如下图

  • 发现阶段
    • CEPOCH:Follower进程向准Leader发送自己处理过的最后一个事务Proposal的epoch值。
    • NEWEPOCH:准Leader 进程根据接收的各进程的epoch,来生成新一轮周期的epoch 值。
    • ACK-E:Follower 进程反馈准 Leader 进程发来的NEWEPOCH消息。
  • 同步阶段

    • NEWLEADER:准Leader进程确立自己的领导地位,并发送NEWLEADER消息给各进程。
    • ACK-LD:Follower 进程反馈Leader 进程发来的NEWLEADER 消息。
    • COMMIT-LD:要求 Follower进程提交相应的历史事务Proposal。
  • 广播阶段

    • PROPOSE:Leader 进程生成一个针对客户端事务请求的Proposal。
    • ACK:Follower进程反馈 Leader进程发来的PROPOSAL消息。
    • COMMIT:Leader发送COMMIT消息,要求所有进程提交事务PROPOSE。

以上就是漫谈ZAB协议系列的全部内容,谢谢小伙伴们的浏览~~

文章转载自糖爸的架构师之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论