2pc_two phase commit详情

2024-08-31 15:48
文章标签 commit two 详情 2pc phase

本文主要是介绍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.假设前提

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

  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详情的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124332

相关文章

监听器(Listener)使用详情

https://www.cnblogs.com/xdp-gacl/p/3969249.html 孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十五)——监听器(Listener)学习二 一、监听域对象中属性的变更的监听器   域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest

git commit -a

今天提交git时遇到这样一个问题,我在项目里rm掉了许多文件,等到想commit的时候,发现这些被删除的文件都是not staged的状态,这要一个个的去git rm就太蛋疼了。这时候就发现了git commit -a这个命令。 OPTIONS-a, --allTell the command to automatically stage files that have been modif

C语言之预处理详情

目录 前言1.预定义符号2.#define定义常量3.#define定义宏4.带有副作用的宏参数5.宏替换的规则6.宏和函数的对比7.#和##运算符7.1 #运算符7.2 ##运算符 8.命名约定9.undef10.命令行指令11.条件编译12.头文件的包含12.1 头文件包含方式12.1.1 本地头文件包含12.1.2 库文件包含 12.2 嵌套文件包含 13.其他预处理指令总结

Java多线程编程模式实战指南:Two-phase Termination模式

文章来源: http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-two-phase-termination?utm_source=infoq&utm_campaign=user_page&utm_medium=link 文章代码地址: https://github.com/Visce

git查看、修改、删除属性,配置提交commit用户名和邮箱

1. 查看 查看所有 git config --list git config --worktree --list git config --local --list git config --global --list git config --system --list 2. 设置 git config --local user.n

解锁京东商品详情宝库:开发者必备API利器与实战应用指南

在当今这个数据驱动的时代,电商平台的数据资源无疑成为了企业竞争的核心优势之一。京东,作为中国电商领域的佼佼者,其商品详情数据更是蕴藏着巨大的商业价值。对于开发者而言,掌握京东商品详情数据API接口,就如同手握一把开启财富之门的钥匙,能够轻松解锁这座数据宝库,为企业的决策、运营乃至创新提供强有力的支持。联系我获取 京东商品详情数据API接口的重要性与价值 京东商品详情数据API接口,是京东开放平

git commit -am

当修改已经通过git add <change file>将其添加到stage,可以通过git commit -m "<message>"为这所有已经进入stage的改变添加一个commit信息。什么是在stage中?看下面 如果你的文件之前已经提交过,但这次的改动还没有进stage,如下: 可以直接使用git commit -am "<message>",将所有修改,但未进s

Mysql中的隐式COMMIT以及Savepoints的作用以及MySQL的Innodb分空间存储、设计优化、索引等几个小知识点整理

一、Mysql中的隐式COMMIT以及Savepoints的作用     Mysql默认是自动提交的,如果要开启使用事务,首先要关闭自动提交后START TRANSACTION 或者 BEGIN 来开始一个事务,使用ROLLBACK/COMMIT来结束一个事务。但即使如此,也并不是所有的操作都能被ROLLBACK,以下语句在执行后会导致回滚失效,比如DDL语句创建一个数据库,而且不止此,这样的语

Oracle 忘了commit

今天在插入数据的时候忘了写commit. 导致后面的插入任务等了好久。

[LeetCode] 583. Delete Operation for Two Strings

题:https://leetcode.com/problems/delete-operation-for-two-strings/description/ 题目 Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in