文章目录

  • 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.假设前提

该协议以以下假设方式工作:

  1. 将一个节点指定为coordinator,即主站点,将网络中的其余节点称为cohorts(同类)。
  2. 每个站点的存储都是稳定的以及每个节点都使用的预写日志(先写日志再执行操作)。
  3. 该协议还假设没有节点永久崩溃,并且最终任何两个节点都可以相互通信。后者并不算十分苛刻,因为通常可以重新路由网络通信。前者是一个非常强的假设(想想假设机器炸毁了!)

很多博客在介绍2pc的时候这些前提假设都完全没有提

2. 算法概述

在阶段1期间

  1. coordinator发送commit-request 给所有cohorts。然后,它等待所有cohorts的返回。对于cohorts来说,如果事务执行成功,则该cohort将一个条目写入undo-log,并将一个条目写入redo-log。
  2. 然后,cohorts回复一个一个agree的信息,如果事务在cohorts节点执行失败,则返回abort信息。

在阶段2期间

  1. 如果coordinator从所有cohorts接收到同意消息,则它将提交记录写入其日志中,并向所有cohorts发送commit消息。
  2. 如果并不是所有的cohorts回复的都是agree消息,则coordinator将发送abort消息。
  3. 接下来,coordinator等待cohorts的确认。当收到来自所有cohorts的ack时,coordinator会将完整的记录写入其日志。注意,coordinator将永远等待直到所有的ack返回。
  4. 如果cohorts收到的是commit消息,它将释放在事务处理期间持有的所有锁和资源,并将ack消息发送给协调者。如果收到的是abort消息,则将使用undo-log撤消该事务,并释放在事务期间持有的资源和锁。然后发送一个ack消息。

上面的描述实际上还不算非常清晰,只能算是一个大概的描述,后面会更清晰的描述这个过程。

3. 缺点

  1. 两阶段提交协议的最大缺点是它是阻塞协议。节点在等待消息时将阻塞。这意味着其他进程将不得不等待被阻塞进程持有的锁资源释放。即使所有其他站点都发生故障,单个节点也将继续等待。如果coordinator永久失败,则某些cohorts将永远无法解决其事务,这会导致永久占用锁资源。

  2. 另一个缺点是该协议过于保守。它更关注abort的情况而不是agree的情况(不管有多少个agree,有一个abort就不行)

附加一些自己的理解,这里的过于保守会导致两个主要的问题
1.因为某个节点不行导致事务无法提交
2.因为某个节点比较慢导致短板效应,每个事务的处理都会很慢,整个系统的吞吐量上不去

4. 详情

这里更加详细的介绍一下2pc理论的过程

1. coordinator 端来看

  1. coordinator将prepare消息发送到每个cohort, coordinator现在处于准备事务状态
  2. 现在,coordinator正在等待每个cohort的响应。如果任何cohort响应ABORT,则必须abort该事务,会执行步骤5。如果所有cohorts都同意,则可以提交该事务,继续执行步骤3。如果过了一段时间,所有cohorts没有响应,那么coordinator可以发送向所有cohort发送abort消息,或将COMMIT-REQUEST消息发送给尚未响应的cohort。无论哪种情况,coordinator最终都将进入状态3或状态5。
  3. 在日志中记录一个COMPLETE,以指示事务现在正在进行complete阶段。然后向每个cohorts发送COMMIT消息。
  4. 等待每个cohorts做出回应。他们必须回复COMMIT。如果一段时间之后,某些cohort没有响应,则重新发送COMMIT消息。一旦所有cohorts均已回复,从永久存储器中擦除所有执行这次事务的相关辅助型信息。完成。
  5. 向每个 cohort 发送abort信息.

2. cohorts端

  1. 如果在COHORT上收到某个事务t的COMMIT-REQUEST消息,该消息在COHORT中是无法被执行的,回复ABORT。反之,将事务的新状态写入永久存储中的UNDO和REDO日志中。这样的话就可以完成恢复旧状态(在以后被abort的情况下)或commit,而不用担心崩溃。事务的读取锁可能在此时被释放;但是,写锁仍然需要保留。然后发送agree 给coordinator。
  2. 如果收到ABORT消息,则终止该事务,利用undo-log恢复到事务发生之前的状态。
  3. 如果收到COMMIT消息,则说明该事务已准备好提交或已经提交。如果已准备好,则执行更新数据库并释放事务拥有的其余锁。如果已经提交,则无需采取进一步措施。回复给coordinator。

5. 正确性分析

我们声称,如果一个cohort完成了事务,那么所有cohort最终都会完成事务。
正确性的证明有些非正式:
如果一个COHORT正在完成一个事务,那是因为coordinateor向它发送了COMMT消息。仅当coordinator处于提交阶段时才发送此消息,在这种情况下,所有COHORTS均已响应coordinateor AGREED。这意味着所有cohorts均已准备好事务,这意味着此时任何崩溃都不会损害事务数据,因为它的redo/undo log位于永久存储中。coordinator完成后,在删除coordinator的数据之前,会确保确保每个corhort都完成了。因此,coordinateor的崩溃不会影响结果。

6. 简单总结

  这里有几个比较重要的点

  1. 一个是几个假设
  2. 还有就是coordinator在第二个阶段进行commit的时候会等待所有节点的ack回来才结束,要不然就会一直重试的发送commit信息。
  3. 因为采用的都是先记录log后操作的方式( write ahead log),所以不用担心宕机可能导致数据丢失。
  4. 在开头说的不2pc协议不会用来处理超过一个节点宕机的描述还不是很清楚,感觉好像多节点宕机也没有问题的样子。
  5. 同样的,在这里coordiantor宕机后不会选新的,而是等待他fail-over之后继续担当coordinator。
  6. 很多博客在介绍2pc的时候完全不提假设,而且,交互过程完全是随心推论,很多地方都不严谨,看的我云里雾里的,大家有精力还是翻翻英文文档吧,我这里可能有些地方翻译的也不一定对,文末有英文原文出处链接。
  7. 整体来看,2pc对外部环境要求非常严格,而且容易产生阻塞,所以在生产环境中直接使用2pc作为分布式一致性实现的系统几乎没有,但是很多系统有优化后的实现,比如微软的PacificA协议的数据复制阶段就是在2pc上加一改造,引入了一个ISR队列来改善了阻塞的问题。

参考
1. 英文原文
2.wiki

2pc_two phase commit详情相关推荐

  1. 3pc_three phase commit protocol协议理解

    文章目录 1. 简介 2. three phase commit协议概览 3. 协议介绍 1. 协议假设 2. 协议详情 1. 阶段一 2. 阶段二 3. 阶段三 4. 一些定义 5. 导致block ...

  2. 两阶段提交协议(two phase commit protocol,2PC)详解

    一.协议概述 两阶段提交协议(two phase commit protocol,2PC)可以保证数据的强一致性,许多分布式关系型数据管理系统采用此协议来完成分布式事务.它是协调所有分布式原子事务参与 ...

  3. Git查看commit详情

    git log 查看所有的commit提交记录 git show 查看提交的详情 1.查看最新的commit git show 2.查看指定commit hashID的所有修改: git show c ...

  4. java 二阶段提交,二阶段提交协议(Two Phase Commitment Protocol)

    一.典型的分布式事务实例 跨行转账问题是一个典型的分布式事务,用户A向B的一个转账1000,要进行A的余额-1000,B的余额+1000,显然必须保证这两个操作的事务性. 类似的还有,电商系统中,当有 ...

  5. 如何让git commit更简洁

    第一步:学会合并commit 同一个任务commit提交了好多次,不够简洁,使用下面的方法,让你实现一个任务只有一个commit,简洁干净 # 查看有日志,看哪些提交需要处理 git log # gi ...

  6. Git commit 撤销提交与查看提交的内容

    撤销最近commit git reset --soft HEAD^ 查看所有commit记录 git log 查看最新的commit详情 git show 查看指定commit hashID的详情: ...

  7. java 面试题汇总

    文章转自与:https://blog.csdn.net/weixin_38399962/article/details/80358168 JAVA基础 JAVA中的几种基本类型,各占用多少字节?   ...

  8. InnoDB事务结构体代码变量列表

    事务结构 struct trx_t 写在前面 InnoDB是MySQL的一个存储引擎,支持事务,支持非堵塞的一致性读,物理存储结构是Page,每个事务都有回滚日志,重做日志,事务还会有死锁检测,各种各 ...

  9. binlog关闭事务记录_MySQL的CrashSafe和Binlog的关系-爱可生

    0 - 什么是CrashSafe CrashSafe指MySQL服务器宕机重启后,能够保证: - 所有已经提交的事务的数据仍然存在. - 所有没有提交的事务的数据自动回滚. 前面的文章讲过,Innod ...

最新文章

  1. python获取数组中大于某一阈值的那些索引值_java矩阵计算及其在统计中的应用(一)...
  2. 【我的Android进阶之旅】如何快速寻找Android第三方开源库在Jcenter上的最新版本...
  3. 自动化监控--zabbix中的用户和用户组详解
  4. 数据库视频(二)——增删改查
  5. 服务器版Windows7系统,windows7服务器版本
  6. python爬虫学习:电商数据分析
  7. 《测试驱动数据库开发》——1.2 谁是目标读者
  8. 7007.svg用法
  9. AI助特朗普当选?FB史上最大数据滥用曝光,牵出ACL终身奖得主
  10. linux控制windows关机
  11. centos lnmp一键安装
  12. c语言10h,bios 10h中断是什么意思啊?
  13. iphone计算机显示过程,iphone怎么同步显示到电脑
  14. Linux align函数,linux内核中ALIGN解析(示例代码)
  15. ❤ ❤html canvas面向对象的彩色小球❤ ❤
  16. vue框架 做后台管理系统的总结(WZ)
  17. Laravel开发的小程序后台管理系统
  18. 新西兰奥克兰发生三车追尾事故 造成一死一伤
  19. 帮忙写基于SSM框架的购物商城管理系统
  20. 文档生成模型:多元贝努利vs多项式

热门文章

  1. 网骗欺诈?网络裸奔?都是因为 HTTP?
  2. C++ 泛型编程(二):非类型模板参数,模板特化,模板的分离编译
  3. 顶级c程序员之路 基础篇 - 第一章 关键字的深度理解 number-1
  4. MySQL:为什么用limit时,offset很大会影响性能
  5. 很现实、很暴力的面试法则 —— 来自招聘官的自述
  6. [八]RabbitMQ-客户端源码之ChannelN
  7. 如何学习 Go 语言的核心知识
  8. C++中的多态(一)
  9. 音视频技术开发周刊 | 160
  10. Netflix如何节省92%视频编码成本?