写在前面
定义
2PC,是 Two-Phase Commit 的缩写,即二阶段提交,是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和一致性而设计的一种算法。通常,二阶段提交协议也被认为是一种一致性协议,用来保证分布式系统数据的一致性。目前,绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务处理的,利用该协议能够非常方便地完成所有分布式事务参与者的协调,统一决定事务的提交或回滚,从而能够有效地保证分布式数据一致性,因此二阶段提交协议被广泛地应用在许多分布式系统中。
提交事务请求(投票阶段)
事务询问:协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。 执行事务:各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中。 各参与者向协调者反馈事务询问的响应
如果参与者成功执行了事务操作,那么就反馈给协调者 Yes 响应,表示事务可以执行。 如果参与者没有成功执行事务,那么就反馈给协调者No响应,表示事务不可以执行。
执行事务提交
假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务提交。
发送提交请求:协调者向所有参与者节点发出Commit 请求。 事务提交:参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源。 反馈事务提交结果:参与者在完成事务提交之后,向协调者发送 ACK 消息。 完成事务:协调者接收到所有参与者反馈的ACK 消息后,完成事务。
中断事务
发送回滚请求:协调者向所有参与者节点发出 Rollback 请求。 事务回滚:参与者接收到Rollback 请求后,会利用其在阶段一中记录的 Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源。 反馈事务回滚结果:参与者在完成事务回滚之后,向协调者发送 Ack 消息。 中断事务:协调者接收到所有参与者反馈的Ack消息后,完成事务中断。
以上就是二阶段提交过程中,前后两个阶段分别进行的处理逻辑。简单地讲,二阶段提交将一个事务的处理过程分为了投票和执行两个阶段,其核心是对每个事务都采用先尝试后提交的处理方式,因此也可以将二阶段提交看作一个强一致性的算法。
优缺点
优点:原理简单,实现方便。
缺点:
同步阻塞
二阶段提交协议存在的最明显也是最大的一个问题就是同步阻塞,这会极大地限制分布式系统的性能。在二阶段提交的执行过程中,所有参与该事务操作的逻辑都处于阻塞状态,也就是说,各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。
数据不一致
在二阶段提交协议的阶段二,即执行事务提交的时候,当协调者向所有的参与者发送Commit请求之后,发生了局部网络异常或者是协调者在尚未发送完Commit 请求之前自身发生了崩溃,导致最终只有部分参与者收到了Commit 请求。于是,这部分收到了Commit 请求的参与者就会进行事务的提交,而其他没有收到Commit 请求的参与者则无法进行事务提交,于是整个分布式系统便出现了数据不一致性现象。
具体步骤
客户端发起一个写操作请求。 Leader 服务器将客户端的请求转化为事务 Proposal 提案,同时为每个 Proposal 分配一个全局的ID,即zxid。 Leader 服务器为每个 Follower 服务器分配一个单独的队列,然后将需要广播的 Proposal 依次放到队列中,并且根据 FIFO 策略进行消息分发。这样做可以做到异步解耦。Leader 和 Follower 之间只需要往队列中发消息即可。如果使用同步的方式会引起阻塞,性能要下降很多。
Follower 接收到 Proposal 后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向 Leader 反馈一个 Ack 响应消息。 Leader 接收到超过半数以上 Follower 的 Ack 响应消息后,即认为消息发送成功,可以发送 commit 消息。 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协议系列的全部内容,谢谢小伙伴们的浏览~~