2pc_two phase commit详情
文章目录
- 1. two phase commit protocol
- 1.假设前提
- 2. 算法概述
- 3. 缺点
- 4. 详情
- 1. coordinator 端来看
- 2. cohorts端
- 5. 正确性分析
- 6. 简单总结
看2pc和3pc看的晕晕乎乎的,看了很多博客,感觉说的都不够细致,看起来也容易犯晕,找到了两篇英文文档(不算原文),看起来好像是清楚一些,有些时候这些协议类的东西研读,如果不是那种特别长的建议直接阅读原文,或者原文阅读作为辅助,可以更快的全面了解,这一篇就算是英文文档的翻译吧。
1. two phase commit protocol
两阶段提交协议是一种分布式算法,它使分布式系统中的所有站点都同意提交事务。该协议保证即使在站点故障和消息丢失的情况下,所有节点都能统一保持提交或abort事务。
但是,该协议将不能处理多个随机站点同时故障(超过一个)的情况。该算法的两个阶段分为COMMIT-REQUEST阶段和COMIT阶段,在COMMIT-REQUEST阶段,coordinator尝试让所有的cohorts完成准备,在COMMIT阶段,coordinator完成所有cohorts的事务。
1.假设前提
该协议以以下假设方式工作:
- 将一个节点指定为coordinator,即主站点,将网络中的其余节点称为cohorts(同类)。
- 每个站点的存储都是稳定的以及每个节点都使用的预写日志(先写日志再执行操作)。
- 该协议还假设没有节点永久崩溃,并且最终任何两个节点都可以相互通信。后者并不算十分苛刻,因为通常可以重新路由网络通信。前者是一个非常强的假设(想想假设机器炸毁了!)
很多博客在介绍2pc的时候这些前提假设都完全没有提
2. 算法概述
在阶段1期间
- coordinator发送commit-request 给所有cohorts。然后,它等待所有cohorts的返回。对于cohorts来说,如果事务执行成功,则该cohort将一个条目写入undo-log,并将一个条目写入redo-log。
- 然后,cohorts回复一个一个agree的信息,如果事务在cohorts节点执行失败,则返回abort信息。
在阶段2期间
- 如果coordinator从所有cohorts接收到同意消息,则它将提交记录写入其日志中,并向所有cohorts发送commit消息。
- 如果并不是所有的cohorts回复的都是agree消息,则coordinator将发送abort消息。
- 接下来,coordinator等待cohorts的确认。当收到来自所有cohorts的ack时,coordinator会将完整的记录写入其日志。注意,coordinator将永远等待直到所有的ack返回。
- 如果cohorts收到的是commit消息,它将释放在事务处理期间持有的所有锁和资源,并将ack消息发送给协调者。如果收到的是abort消息,则将使用undo-log撤消该事务,并释放在事务期间持有的资源和锁。然后发送一个ack消息。
上面的描述实际上还不算非常清晰,只能算是一个大概的描述,后面会更清晰的描述这个过程。
3. 缺点
两阶段提交协议的最大缺点是它是阻塞协议。节点在等待消息时将阻塞。这意味着其他进程将不得不等待被阻塞进程持有的锁资源释放。即使所有其他站点都发生故障,单个节点也将继续等待。如果coordinator永久失败,则某些cohorts将永远无法解决其事务,这会导致永久占用锁资源。
另一个缺点是该协议过于保守。它更关注abort的情况而不是agree的情况(不管有多少个agree,有一个abort就不行)
附加一些自己的理解,这里的过于保守会导致两个主要的问题
1.因为某个节点不行导致事务无法提交
2.因为某个节点比较慢导致短板效应,每个事务的处理都会很慢,整个系统的吞吐量上不去
4. 详情
这里更加详细的介绍一下2pc理论的过程
1. coordinator 端来看
- coordinator将prepare消息发送到每个cohort, coordinator现在处于准备事务状态
- 现在,coordinator正在等待每个cohort的响应。如果任何cohort响应ABORT,则必须abort该事务,会执行步骤5。如果所有cohorts都同意,则可以提交该事务,继续执行步骤3。如果过了一段时间,所有cohorts没有响应,那么coordinator可以发送向所有cohort发送abort消息,或将COMMIT-REQUEST消息发送给尚未响应的cohort。无论哪种情况,coordinator最终都将进入状态3或状态5。
- 在日志中记录一个COMPLETE,以指示事务现在正在进行complete阶段。然后向每个cohorts发送COMMIT消息。
- 等待每个cohorts做出回应。他们必须回复COMMIT。如果一段时间之后,某些cohort没有响应,则重新发送COMMIT消息。一旦所有cohorts均已回复,从永久存储器中擦除所有执行这次事务的相关辅助型信息。完成。
- 向每个 cohort 发送abort信息.
2. cohorts端
- 如果在COHORT上收到某个事务t的COMMIT-REQUEST消息,该消息在COHORT中是无法被执行的,回复ABORT。反之,将事务的新状态写入永久存储中的UNDO和REDO日志中。这样的话就可以完成恢复旧状态(在以后被abort的情况下)或commit,而不用担心崩溃。事务的读取锁可能在此时被释放;但是,写锁仍然需要保留。然后发送agree 给coordinator。
- 如果收到ABORT消息,则终止该事务,利用undo-log恢复到事务发生之前的状态。
- 如果收到COMMIT消息,则说明该事务已准备好提交或已经提交。如果已准备好,则执行更新数据库并释放事务拥有的其余锁。如果已经提交,则无需采取进一步措施。回复给coordinator。
5. 正确性分析
我们声称,如果一个cohort完成了事务,那么所有cohort最终都会完成事务。
正确性的证明有些非正式:
如果一个COHORT正在完成一个事务,那是因为coordinateor向它发送了COMMT消息。仅当coordinator处于提交阶段时才发送此消息,在这种情况下,所有COHORTS均已响应coordinateor AGREED。这意味着所有cohorts均已准备好事务,这意味着此时任何崩溃都不会损害事务数据,因为它的redo/undo log位于永久存储中。coordinator完成后,在删除coordinator的数据之前,会确保确保每个corhort都完成了。因此,coordinateor的崩溃不会影响结果。
6. 简单总结
这里有几个比较重要的点
- 一个是几个假设
- 还有就是coordinator在第二个阶段进行commit的时候会等待所有节点的ack回来才结束,要不然就会一直重试的发送commit信息。
- 因为采用的都是先记录log后操作的方式( write ahead log),所以不用担心宕机可能导致数据丢失。
- 在开头说的不2pc协议不会用来处理超过一个节点宕机的描述还不是很清楚,感觉好像多节点宕机也没有问题的样子。
- 同样的,在这里coordiantor宕机后不会选新的,而是等待他fail-over之后继续担当coordinator。
- 很多博客在介绍2pc的时候完全不提假设,而且,交互过程完全是随心推论,很多地方都不严谨,看的我云里雾里的,大家有精力还是翻翻英文文档吧,我这里可能有些地方翻译的也不一定对,文末有英文原文出处链接。
- 整体来看,2pc对外部环境要求非常严格,而且容易产生阻塞,所以在生产环境中直接使用2pc作为分布式一致性实现的系统几乎没有,但是很多系统有优化后的实现,比如微软的PacificA协议的数据复制阶段就是在2pc上加一改造,引入了一个ISR队列来改善了阻塞的问题。
参考
1. 英文原文
2.wiki
2pc_two phase commit详情相关推荐
- 3pc_three phase commit protocol协议理解
文章目录 1. 简介 2. three phase commit协议概览 3. 协议介绍 1. 协议假设 2. 协议详情 1. 阶段一 2. 阶段二 3. 阶段三 4. 一些定义 5. 导致block ...
- 两阶段提交协议(two phase commit protocol,2PC)详解
一.协议概述 两阶段提交协议(two phase commit protocol,2PC)可以保证数据的强一致性,许多分布式关系型数据管理系统采用此协议来完成分布式事务.它是协调所有分布式原子事务参与 ...
- Git查看commit详情
git log 查看所有的commit提交记录 git show 查看提交的详情 1.查看最新的commit git show 2.查看指定commit hashID的所有修改: git show c ...
- java 二阶段提交,二阶段提交协议(Two Phase Commitment Protocol)
一.典型的分布式事务实例 跨行转账问题是一个典型的分布式事务,用户A向B的一个转账1000,要进行A的余额-1000,B的余额+1000,显然必须保证这两个操作的事务性. 类似的还有,电商系统中,当有 ...
- 如何让git commit更简洁
第一步:学会合并commit 同一个任务commit提交了好多次,不够简洁,使用下面的方法,让你实现一个任务只有一个commit,简洁干净 # 查看有日志,看哪些提交需要处理 git log # gi ...
- Git commit 撤销提交与查看提交的内容
撤销最近commit git reset --soft HEAD^ 查看所有commit记录 git log 查看最新的commit详情 git show 查看指定commit hashID的详情: ...
- java 面试题汇总
文章转自与:https://blog.csdn.net/weixin_38399962/article/details/80358168 JAVA基础 JAVA中的几种基本类型,各占用多少字节? ...
- InnoDB事务结构体代码变量列表
事务结构 struct trx_t 写在前面 InnoDB是MySQL的一个存储引擎,支持事务,支持非堵塞的一致性读,物理存储结构是Page,每个事务都有回滚日志,重做日志,事务还会有死锁检测,各种各 ...
- binlog关闭事务记录_MySQL的CrashSafe和Binlog的关系-爱可生
0 - 什么是CrashSafe CrashSafe指MySQL服务器宕机重启后,能够保证: - 所有已经提交的事务的数据仍然存在. - 所有没有提交的事务的数据自动回滚. 前面的文章讲过,Innod ...
最新文章
- python获取数组中大于某一阈值的那些索引值_java矩阵计算及其在统计中的应用(一)...
- 【我的Android进阶之旅】如何快速寻找Android第三方开源库在Jcenter上的最新版本...
- 自动化监控--zabbix中的用户和用户组详解
- 数据库视频(二)——增删改查
- 服务器版Windows7系统,windows7服务器版本
- python爬虫学习:电商数据分析
- 《测试驱动数据库开发》——1.2 谁是目标读者
- 7007.svg用法
- AI助特朗普当选?FB史上最大数据滥用曝光,牵出ACL终身奖得主
- linux控制windows关机
- centos lnmp一键安装
- c语言10h,bios 10h中断是什么意思啊?
- iphone计算机显示过程,iphone怎么同步显示到电脑
- Linux align函数,linux内核中ALIGN解析(示例代码)
- ❤ ❤html canvas面向对象的彩色小球❤ ❤
- vue框架 做后台管理系统的总结(WZ)
- Laravel开发的小程序后台管理系统
- 新西兰奥克兰发生三车追尾事故 造成一死一伤
- 帮忙写基于SSM框架的购物商城管理系统
- 文档生成模型:多元贝努利vs多项式