7. 对比两阶段提交,三阶段协议有哪些改进?

2023-07-29  本文已影响0人  木叶苍蓝

在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调
在关系型数据库中,由于存在事务机制,可以保证每个独立节点上的数据操作都满足 ACID

两阶段和三阶段提交的具体流程是怎样的?三阶段提交又是如何改进的呢?

协调者统一调度

在分布式事务的定义中,如果想让分布式部署的多台机器中的数据保存一致性
就要保证在所有节点的数据写操作,要么全部都执行,要么全部都不执行
但是,一台机器在执行本地事务的时候无法知道其他机器中本地事务的执行结果
节点并不知道本次事务到底应该 Commit 还是 Rollback

两阶段和三阶段提交协议都是引入了一个协调者的组件来统一调度所有分布式节点的执行
让当前节点知道其他节点的任务执行状态,通过通知和表决的方式
决定执行 Commit 还是 Rollback 操作

两阶段提交协议

两阶段提交算法的成立是基于以下假设的:

提交请求节阶段

协调者将通知事务参与者准备提价事务,然后进入表决过程
在表决过程中,参与者将告知协调者自己的决策
同意(事务参与者本地事务执行成功)或取消(本地事务执行故障)
在第一阶段,参与节点并没有进行 Commit 操作

提交阶段

在提交阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消这个事务
这个结果的处理,必须当且仅当所有的参与者同意提交
协调者才会通知各个参与者提交事务,否则协调者将会通知各个参与者取消事务
参与者在接收到协调者发来的消息后将执行对应的操作
也就是本地 Commit 或者 Rollback

两阶段提交存在的问题
20230729161720.jpg

三阶段提交协议

20230729161837.jpg
CanCommit 阶段

协调者向参与者发送 Commit 请求,参与者如果可以提交就返回 Yes 响应,否则返回 No 响应

PreCommit 阶段
A. 假如协调者从所有的参与者获得的反馈都是 Yes 响应

那么就会进行事务的预执行:

B. 假如有任何一个参与者向协调者 发送了 No 响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就中断事务:
DoCommit 阶段
A. 执行提交
B. 中断事务

协调者没有接收到参与者发送的 ACK 响应
可能是因为接受者发送的不是 ACK 响应,也有可能响应超时,那么就会执行中断事务
####### C. 超时提交
参与者如果没有收到协调者的通知,超市之后会执行 Commit 操作

三阶段提交做了哪些改进

引入超时机制

在 2PC 中,只有协调者拥有超时机制,如果在一定时间内没有收到参与者的消息则默认失败
3PC 同时在协调者和参与者中都引入超时机制

添加预提阶段

在 2PC 的准备阶段和提交阶段之间,插入一个预提交阶段
是 3PC 拥有 CanCommit ,PreCommit,DoCommit 三个阶段
PreCommit 是一个缓冲,保证了在最后提交阶段之前各个参与节点的状态都是一致的

三阶段提交协议存在的问题

在阶段三中,如果参与者接收到了 PreCommit 消息后,出现了不能与协调者正常通信的问题
在这种情况下,参与者依然会进行事务的提交,这就出现了数据的不一致性

两阶段和三阶段提交的应用

两阶段提交是一种比较精简的一致性算法 / 协议
很多关系型数据库都是采用两阶段提交协议来完成分布式事务处理的
典型的比如 MySQL 的 XA 规范
MySQL Cluster 内部数据的同步就是用的 2PC 协议

MySQL 的主从复制

在 MySQL 中

开启 Binlog 后,如何保证 Binlog 和 InnoDB redo 日志的一致性呢?

MySQL 使用的是二阶段提交
内部会自动将普通事务当做一个 XA 事务(内部分布式事务)来处理:

总结

两阶段和三阶段提交协议是众多分布式算法的基础

上一篇下一篇

猜你喜欢

热点阅读