分布式一致性算法2PC和3PC
为了解决分布式一致性问题,产生了不少经典的分布式一致性算法,本文将介绍其中的2PC和3PC。2PC即Two-Phase Commit,译为二阶段提交协议。3PC即Three-Phase Commit,译为三阶段提交协议。
分布式系统和分布式一致性问题
分布式系统,即运行在多台不同的网络计算机上的软硬件系统,并且仅通过消息传递来进行通信和协调。
分布式一致性问题,即相互独立的节点之间如何就一项决议达成一致的问题。
2PC
2PC,二阶段提交协议,即将事务的提交过程分为两个阶段来进行处理:准备阶段 和 提交阶段。事务的发起者称协调者, 事务的执行者称参与者。
阶段1:准备阶段
1、协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。
2、各参与者, 先锁住资源,然后执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。// 就是说 执行sql, 但是不执行 commit
3、如参与者执行成功,给协调者反馈YES,即可以提交;如执行失败 ,给协调者反馈NO (或反馈超时) ,即不可提交。
阶段2:提交阶段
此阶段分两种情况:所有参与者均反馈YES、或任何一个参与者反馈NO。
所有参与者均反馈YES时,即提交事务。
任何一个参与者反馈NO时,即中断事务。
提交事务:(所有参与者均反馈YES)
1、协调者向所有参与者发出正式提交事务的请求(即Commit请求)。// 就是发通知说 准备执行 commit 吧
2、参与者执行Commit请求,并释放整个事务期间占用的资源。// 就是正式的 执行 commit , 提交之后要释放 资源, 因为锁已经释放。
3、各参与者向协调者反馈Ack完成的消息。 // ack 也是不能不忘记的
4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。

中断事务:(任何一个参与者反馈NO)
1、协调者向所有参与者发出回滚请求(即Rollback请求)。
2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。// 就是正式的 执行 rollback,回滚 之后也会 释放 资源, 因为锁已经释放。
3、各参与者向协调者反馈Ack完成的消息。
4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。

小结:
2pc中,参与者没有超时机制, 所以, 如果协调者没有或 没有正确 发生指令过来, 那么 会 一直占用资源。
协调者会等待 参与者的响应, —— 这是2pc 中 唯一的一个超时 时间。
提交事务或 中断 事务 的时候, 协调者 都需要 等待 所有 参与者的 ack, 这个过程可能 参与者、协调者、网络 发生故障,如果 协调者正常且 只收到 部分 ack, 怎么办? 事务是否要 继续 完成? 还是记为 待 完成状态? 比较郁闷的是,找了很多的 博客, 没有看到 对这个问题有进行说明的。。 我感觉是 先会记录为待 完成, 然后 要么协调者 停止工作; 要么 发出 error 警告后 继续工作。
2PC的缺陷
1、同步阻塞:最大的问题即同步阻塞,即:所有参与事务的逻辑均处于阻塞状态。
2、单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。
3、脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。// 就是“提交事务”的时候, 协调者只有收到部分的ack.
由于2PC存在如上同步阻塞、单点、脑裂问题,因此又出现了2PC的改进方案,即3PC。
3PC

3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、do Commit三个阶段来进行处理。
阶段1:CanCommit
1、协调者向所有参与者 发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。—— 这里的 等待 肯定有 超时机制
2、参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态(某个参与者进入预备状态之后, 它会等待 协调者的响应, 这里也有超时机制, 如果超时了, 那么直接 abort ! ),否则反馈NO。 —— 参与者 需要负责 检测资源是否足够, 然后 “预留” 资源。 但是, 这一步骤, 参与者 不会锁住资源。。 预留 不是锁。
阶段2:PreCommit
此阶段分两种情况:
1、所有参与者均反馈YES,即执行事务预提交。
2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
事务预提交:(所有参与者均反馈YES时)
1、协调者向所有参与者发出PreCommit请求,进入准备阶段。
2、参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。—— 锁住资源, 执行事务, 参与者向协调者反馈Ack响应或No响应,并等待最终指令。然后 进入 等待状态, 超时后就直接提交, 为什么呢? 因为进入了 这一步骤, 那么一定是 CanCommit 阶段所有的参与者都是返回yes—— 如果这个时候 协调者又发送了 abort 命令呢? 。
中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
1、协调者向所有参与者发出 abort 请求。
2、无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。
阶段3:do Commit
此阶段也存在两种情况:
1、所有参与者均反馈Ack响应,即执行真正的事务提交。
2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
提交事务:(所有参与者均反馈Ack响应时)
1、如果协调者处于工作状态,则向所有参与者发出do Commit请求。
2、参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源。并且, 各参与者向协调者反馈Ack完成的消息。
3、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。( 无论如何, 都得完成 这个事务 )
中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
1、如果协调者处于工作状态,向所有参与者发出abort请求。 // 如果 协调者处于非工作状态, ??
2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。并且, 各参与者向协调者反馈Ack完成的消息。
3、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
注意:进入阶段三后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的do Commit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。
3PC的优点和缺陷
优点:降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。 ???
缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
后记
无论2PC或3PC,均无法彻底解决分布式一致性问题。
解决一致性问题,唯有Paxos,后续将单独总结。
3pc 其实 相对于 2pc 就是多了一个CanConmmit 阶段, 这个阶段的作用呢? 我想 就是 保证各个 参与者与 协调者 的网络是ok 的,避免 “参与者 立即 执行事务操作” !
但是不管是2PC还是3PC都存在数据一致性的问题:
2PC:比如协调者在只给部分参与者发送了Commit请求,那就会出现部分参与者执行了Commit,部分没有提交 ( 会一直阻塞 等待!),出现不一致问题。
3PC:在第三阶段,一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态,但是这种机制也会导致数据一致性问题—— 万一 协调者需要的是 abort 呢? 因为 可能协调者 执行延迟发送数据而已。。
还有想要说的是, 2pc 或 3pc 也好, 有没有明确的限定 阶段 的操作? 我认为是有的, 首先要区分是协调者还是参与者, 然后再看具体情况:
对于 2pc:
协调者一开始处于准备阶段, 发送事务及 询问 后, 然后等待反馈。 但参与者还没有,协调者虽然发送出去了, 但是参与者还没有立即收到, 有一定的网络延迟。 参与者收到了之后, 参与者就算正式进入了 准备阶段。 然后参与者 进行sql操作(并不提交),然后 反馈Yes 或者 No。 这个时候, 反馈已经完毕, 参与者就算了 准备完成了。
参与者等待反馈超时,进入中断流程,完了准备阶段 结束, 但是没有进入提交阶段。
然后,协调者收到了各个参与者的反馈, 然后,
如果有一个是No,然后进入中断流程,完了准备阶段 结束, 但是没有进入提交阶段。
如果都是Yes,然后协调者就算是进入了提交阶段,协调者向各个参与者发送Commit命令,完了就等待响应。
参与者并不知道 协调者会发送什么命令过来, 会一直 一直等待。 如果收到了Commit命令,那么就算是进入了提交阶段, 然后正式的 commit, 然后反馈ack(Y 还是N ?这个时候 有可能反馈N 吗?), 然后完成 提交阶段。这个时候参与者是完成了提交阶段, 但是协调者还没有。
协调者如果收到了所有的node 反馈ack, 那么就结束 提交阶段。 (如果不呢?)
注意,各个阶段直接是没有 其他多余的操作的, 也就是没有其他阶段了!
简单说 2pc是这样的,其一,协调者在第一次发送之后 进入阶段一,要么超时时间内收到反馈, 然后处理,然后结束第一阶段; 要么超时后处理,然后结束第一阶段。 发生在这个阶段内的 中断处理也算是 第一阶段的内容。 其二, 协调者在第二次发送之 后进入阶段二,只有一个选择,全部提交,然后收集所有反馈, 没有超时机制(原因待查)。
简单说 3pc是这样的, 它有4个超时时间, 第一阶段,协调者等待 参与者(记为T1),参与者响应后等待协调者(记为T2),第二阶段,协调者等待 参与者(记为T3),参与者响应后等待协调者(记为T4),出现其中任何的一个,那么中断。
通常认为执行sql(但不提交), 是可能会失败的, 这里必须做确认检查, 要保证所有节点都Yes否则就中断, 但是最后阶段的 执行 commit 或 rollback 是不会失败的, 故我们没有对 commit 或 rollback 的成功还是失败做检查( 不清楚为什么,可能是因为这些操作没有占据新的 资源的原因吧。但是试想,如果每个操作都要检查, 那么相互之间通信就会没玩没了。 或许需要对比一下 paxos 算法了)。
90% 转载:
http://blog.51cto.com/11821908/2058651
https://www.cnblogs.com/shangxiaofei/p/5196260.html
https://www.jianshu.com/p/dd6a340e50b2
分布式一致性算法2PC和3PC的更多相关文章
- 分布式一致性算法 2PC 3PC Paxos
分布式一致性算法的目的是为了解决分布式系统 一致性算法可以通过共享内存(需要锁)或者消息传递实现,本文讨论后者实现的一致性算法,不仅仅是分布式系统中,凡是多个过程需要达成某种一致的场合都可以使用. 本 ...
- 分布式一致性协议-2PC与3PC(二)
一.分布式一致性 一个事务需要跨多个分布式节点,又要保持事务的ACID特性,需要引入协调者来统一调度所有分布式节点的执行逻辑,被调度的节点称为参与者. 协调者负责调用参与者,并决定最终是否提交事务.基 ...
- 分布式事务(1)---2PC和3PC理论
分布式事务(1)---2PC和3PC理论 分布式事物基本理论:基本遵循CPA理论,采用柔性事物特征,软状态或者最终一致性特点保证分布式事物一致性问题. 分布式事物常见解决方案: 2PC两段提交协议 3 ...
- 分布式一致性算法:Raft 算法(论文翻译)
Raft 算法是可以用来替代 Paxos 算法的分布式一致性算法,而且 raft 算法比 Paxos 算法更易懂且更容易实现.本文对 raft 论文进行翻译,希望能有助于读者更方便地理解 raft 的 ...
- 分布式一致性算法——paxos
一.什么是paxos算法 Paxos 算法是分布式一致性算法用来解决一个分布式系统如何就某个值(决议)达成一致的问题. 人们在理解paxos算法是会遇到一些困境,那么接下来,我们带着以下几个问题来学习 ...
- 【转】Raft 为什么是更易理解的分布式一致性算法
编者按:这是看过的Raft算法博客中比较通俗的一篇了,讲解问题的角度比较新奇,图文并茂,值得一看.原文链接:Raft 为什么是更易理解的分布式一致性算法 一致性问题可以算是分布式领域的一个圣殿级问题了 ...
- 【转】分布式一致性算法:Raft 算法(Raft 论文翻译)
编者按:这篇文章来自简书的一个位博主Jeffbond,读了好几遍,翻译的质量比较高,原文链接:分布式一致性算法:Raft 算法(Raft 论文翻译),版权一切归原译者. 同时,第6部分的集群成员变更读 ...
- 三:分布式事务一致性协议2pc和3pc
一:分布式一致性协议--->对于一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议.--->长期探索涌现出一大批经典的一 ...
- 分布式系统理论基础1: 一致性、2PC和3PC
本文转自 https://www.cnblogs.com/bangerlee/p/5268485.html 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到 ...
随机推荐
- JVM垃圾回收机制之对象回收算法
前言 在前面的文章中,介绍了JVM内存模型分为:堆区.虚拟机栈.方法区.本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此区域,它能被所有线程共享. 在 ...
- Linux 开(关) ICMP 回应(防止被ping)
临时生效的办法 关闭回应: [root@host ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all // 客户端测试 ➜ ~ ping 0 ...
- req和resp常用的方法
req: 1. setAttribute()在Request域中存储数据 2. setCharacterEncoding()设置请求参数的编码方式,只对post请求有效 3. getMethod() ...
- QCAD 修改默认的线宽
QCAD 修改默认的线宽 默认的宽度实在是太宽了,把一些细节给掩盖了. 可以按以下方法找到修改默认宽度. 在 Layer -> Edit Layer 中. 最开始找了好久好久. 最开始在这里找了 ...
- VCenter6.0.0的安装过程
背景和实验环境介绍 操作系统环境:windows 2008R2 中文企业版 前期环境配置 配置IP信息,把DNS改成自己的IP 修改主机名和后缀 安装和配置DNS服务 Vcenter 添加dns角色 ...
- 20175202 《Java程序设计》第五周学习总结
20175209 2018-2019-2 <Java程序设计>第五周学习总结 教材知识点总结 1.接口声明: 使用关键字interface来定义接口. 定义接口时使用关键字interfac ...
- js驗證網址URL格式
/^((ht|f)tps?):\/\/([\w\-]+(\.[\w\-]+)*\/)*[\w\-]+(\.[\w\-]+)*\/?(\?([\w\-\.,@?^=%&:\/~\+#]*)+)? ...
- operator用法:隐式类型转换
operator它有两种用法,一种是operator overloading(操作符重载),一种是operator casting(操作隐式转换). 1.操作符重载C++可以通过operator实现重 ...
- MVC5 方法扩展
public static MvcHtmlString DataDictionaryDropDownList(this HtmlHelper htmlHelper, string name, obje ...
- SQL数据库日志清理
USE [master] GO ALTER DATABASE HCPM_01_181230 SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE HCP ...