事务 - 2PC

2PC

github

上一篇文章中我们介绍了本地事务,随着软件复杂度的上升,我们会需要一种可以在多个数据库之间完成事务(分布式事务)的方法,而这个方法也必须能够保证ACID。于是就出现了2PC - Two phase commit protocol。事实上2PC不仅仅适用于多数据库事务场景下使用,也适用于所有支持2PC的参与方(Participants)。

算法介绍

2PC的参与方有:

  1. 一个作为Coordinator的节点
  2. 多个作为Cohort的网络节点

2PC假设:

  1. 所有节点都有一个稳定存储用以保存WAL(write-ahead log
  2. 没有一个节点会永远崩溃(即会最终恢复)
  3. write-ahead log中存储的数据永远不会丢失,不会因崩溃而损坏
  4. 任意两个节点都能够互相通信

第四个假设太过严格,实际上有不是所有的2PC实现都满足。第一、二个假设则大多数2PC实现都能满足。

PS. 如果某个节点完全损坏(比如服务器物理损毁),那么数据就直接丢失了。

2PC的执行步骤:

  1. Commit request phase /Voting phase。这个阶段做:
    1. Coordinator发送一个查询是否同意commit的请求到所有Cohort,并且等待所有Cohort给出应答。
    2. Cohort收到请求,开始执行事务,执行到就差commit为止(不commit)。
    3. 每个Cohort根据操作结果返回Yes或No
  2. Commit phase / Completion phase。这个阶段分两种情况:
    1. 成功。所有Cohort应答Yes
      1. Coordinator发送commit指令到所有Cohort
      2. 每个Cohort执行commit,并发送ack到Coordinator
      3. 当Coordinator收到每个Cohort的ack之后则事务完成
    2. 失败。任意Cohort应答No,或者在commit request阶段超时
      1. Coordinator发送rollback指令到所有Cohort
      2. 每个Cohort执行rollback,并发送ack到Coordinator
      3. 当Coordinator收到每个Cohort的ack之后则事务撤销

消息流(摘自wiki):

Coordinator                                         Cohort
                              QUERY TO COMMIT
                -------------------------------->
                              VOTE YES/NO           prepare*/abort*
                <-------------------------------
commit*/abort*                COMMIT/ROLLBACK
                -------------------------------->
                              ACKNOWLEDGMENT        commit*/abort*
                <--------------------------------  
end

2PC的通信次数是:

  1. 如果实现没有要求任意两个Cohort可以通信,那么是2n(n=Cohort数量)
  2. 如果实现要求任意两个Cohort可以通信,那么是n^2

异常处理

我们把上面的流程简化以便说明异常处理:

  1. Coordinator发送query to commit
  2. Cohort执行prepare
  3. Cohort返回ack
  4. Coordinator发送commit/rollback
  5. Cohort执行commit/rollback
  6. Cohort返回ack

从Coordinate角度来看出现异常要怎么处理:

  1. step 1发生异常,Coordinator需要执行rollback
  2. step 2、3发生异常,意味着Coordinator没有收到Cohort的响应,这个时候因认定为失败,执行rollback
  3. step 4发生异常,Coordinator重试commit/rollback
  4. step 5、6发生异常,意味着Coordinator没有收到Cohort的响应,这个时候因认定为失败,重试commit/rollback

从Cohort角度来看看看出现异常怎么处理:

  1. step 1,意味着Cohort没有收到请求,什么都不需要做
  2. step 2,意味着Cohort没有执行成功,什么都不需要做
  3. step 3,意味着Coordinator没有收到结果,什么都不需要做,等待Coordinator重试即可。Cohort要保证prepare是幂等的。
  4. step 4,等待Coordinator重试即可,这里有点tricky,如果Coordinator迟迟不retry,那么Cohort要自行rollback,否则就会造成资源死锁。
  5. step 5,等待Coordinator重试即可
  6. step 6,意味着Coordinator没有收到结果,什么都不需要做,等待Coordinator重试即可,Cohort要保证commit/rollback是幂等的。

观察一下你就会发现依然存在漏洞——会出现违反一致性的情况:

  1. 若Coordinator/Cohort因崩溃遗失了信息,有的Cohort已commit,有的Cohort则恢复到commit之前的状态。
  2. 若Coordinator在step 4发送commit,而Cohort在rollback(因timeout导致的rollback)。

出现上面的情况就需要人工介入了。

更多2PC的异常处理推理详见这篇slides

缺点

根据上面的算法介绍可以看出2PC是一个阻塞协议:

  • 如果两个事务针对同一个数据,那么后面的要等待前面完成,这是由于Cohort采用的是本地事务所决定的
  • Cohort在commit request phase之后会阻塞,直到进入Coordinator告之Cohort进入commit phase

对于ACID的保证

2PC所保证的ACID和本地事务所提到的ACID不太一样——事实上对于所有分布式事务来说都不太一样:

  • A,正常情况下保证
  • C,在某个时间点,会出现A库和B库的数据违反一致性要求的情况
  • I,在某个时间点,A事务能够读到B事务部分提交的结果
  • D,和本地事务一样,只要commit则数据被持久

XA

XA是一个针对分布式事务的spec,它实现了2PC协议。在XA中定义了两种参与方:Transaction Manager(TM)和Resource Manager(RM),其中TM=2PC中的Coordinator,RM=2PC中的Cohort。

Java规范中的JTA(Java Transaction API)定义了XA的Java接口,JTA的实现有Bitronix、Atomikos等等。

参考资料

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏李家的小酒馆

UDP和TCP的区别

UDP(User Data Protocol,用户数据报协议)   UDP是一个无连接,不保证可靠性的传输层协议,也就是说发送端部关心发送的数据是否到达目标主机...

39800
来自专栏LanceToBigData

TCP/IP(四)网络层

前言 前面给大家介绍了计算机网络的基本概述,物理层和数据链路层。这一篇给大家介绍面试中经常会被问到的网络层。在介绍之前我们回顾一下之前学习的知识!   CP/I...

32450
来自专栏代码世界

计算机网络基础

计算机网络的发展及基础网络概念 问题:网络到底是什么?计算机之间是如何通信的? 早期 : 联机 ?  以太网 : 局域网与交换机 ? 广播   主机之间“一对所...

411120
来自专栏Java面试通关手册

搞定计算机网络面试,看这篇就够了(补充版)

相对与上一个版本的计算机网路面试知识总结,这个版本增加了 “TCP协议如何保证可靠传输”包括超时重传、停止等待协议、滑动窗口、流量控制、拥塞控制等内容并且对一些...

25920
来自专栏互联网杂技

开发人员应该知道的计算机网络知识

前言 作为一名程序员, 不可能不与网络打交道. 现在我们的手机, 电脑, 不夸张地说, 离开了网络就是一块’废铁’, 它们的作用将大打折扣.. 本文的作用呢,主...

44250
来自专栏java一日一条

每个程序员应该知道的计算机网络知识

作为一名程序员, 不可能不与网络打交道. 现在我们的手机, 电脑, 不夸张地说, 离开了网络就是一块’废铁’, 它们的作用将大打折扣.. 本文的作用呢, 主要是...

51210
来自专栏腾讯IVWEB团队的专栏

Fis3 构建迁移 Webpack 之路

本篇文章主要介绍从 Fis 迁移到 webpack 遇到的问题和背后的黑科技,内容包括 inline-resource、多页面构建、资源压缩、文件hash、文件...

44620
来自专栏北京马哥教育

又见KeepAlive

最近工作中遇到一个问题,想把它记录下来,场景是这样的: ? 从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是...

55260
来自专栏Golang语言社区

TCP、UDP、IP 协议分析

互连网早期的时候,主机间的互连使用的是NCP协议。这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能。为了改善这种缺点,大牛弄...

51930
来自专栏LuckQI

学习Java基础知识,打通面试关~十二乐观锁与悲观锁

14120

扫码关注云+社区

领取腾讯云代金券