分布式事务学习 - 相关理论和经典解决方案

目录

一、前言

二、相关概念

(一)ACID特性

(二)一致性

(三)CAP定理

(四)BASE理论

三、解决方案

(一)两阶段提交(Two Phase Commitment Protocol,2PC)

(二)补偿事务(Try Confirm Cancel,TCC)

(三)本地消息表

(四)消息队列事务

(五)Sagas事务

四、总结

五、参考资料


一、前言

互联网数据井喷式发展使得单机数据库的性能遇到了瓶颈,这时我们通常会对数据库进行分区,即分库分表,在这种情况下,就需要解决分布式数据库的数据一致性问题,即分布式事务。长期以来,分布式事务都是分布式架构的系统中的一个技术难题,下面我们一起来学习一下分布式事务的相关知识。

二、相关概念

(一)ACID特性

首先,让我们回忆一下数据库事务的ACID特性:

  • 原子性(Atomicity):一个事务中的一个或多个数据库操作,要么全部执行成功,要么全部失败,不会出现部分成功部分失败的情况。
  • 一致性(Consistency):并发事务执行前后系统必须都处于一个稳定的状态,不会出现数据不一致的情况。
  • 隔离性(Isolation):并发执行的事务之间不会相互影响。
  • 持久性(Durability):事务一旦执行成功,数据便永久写入数据库。

ACID特性是传统的单机数据库事务的特性,用于保证数据库的一致性。

(二)一致性

在上面我们提到了一致性问题,这里指的一致性是强一致性,相应的还有弱一致性,即:

1. 强一致性

任何读取数据的操作都能读到最新写入的数据。

2. 弱一致性

数据写入成功后,在后续的读取过程中可能只能读取到部分数据,甚至读取不到,但存在一种特殊情况,即最终一致性,也就是在数据写入成功后,保证在一定的事件内数据达到一致的状态。

(三)CAP定理

CAP定理起源于计算机科学家Eric Brewer在2000年的分布式计算原则研讨会(Symposium on Principles of Distributed Computing(PODC))上提出的一个猜想,他指出WEB服务无法同时满足一下3个属性:

  • 一致性(Consistency):分布式环境中,所有数据的副本在同一时刻是相同的。
  • 可用性(Availability):对于非故障的节点,必须对每一个请求在有限的时间内作出响应。
  • 分区容错性(Partition tolerance):单个节点出现故障,整个系统依然可以提供服务。

既然无法同时满足以上3个属性,那么就需要进行取舍:

组合

说明

CA

放弃分区容错性,加强一致性和可用性,就是传统的单机数据库的选择

AP

放弃强一致性,追求分区容错性和可用性,这是很多分布式系统设计时的选择,例如很多NoSQL系统就是如此

CP

放弃可用性,追求一致性和分区容错性,基本不会选择,网络问题会直接让整个系统不可用

图表参考自:从分布式一致性谈到CAP理论、BASE理论

(四)BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写,分别代表:

  • 基本可用:指分布式系统在出现不可预知故障的时候,允许损失部分可用性,但这绝不等价于系统不可用
  • 软状态:允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时
  • 最终一致性:最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性

三、解决方案

(一)两阶段提交(Two Phase Commitment Protocol,2PC)

顾名思义,两阶段提交即是将事务的提交分为两个阶段进行:准备阶段和提交阶段。这里需要引入两个概念:协调者和参与者,在跨行转账业务中,协调者为事务协调器,参与者为转账双方的数据库。

准备阶段:

  1. 协调者向所有的参与者发出预提交指令,并等待参与者回答。
  2. 参与者接收到预提交指令后,执行本地事务,但不进行提交,同时锁定资源。若参与者执行成功,则向协调者反馈可提交,否则,向协调者反馈不可提交。

提交阶段:

若协调者收到所有参与者可提交的反馈,则向所有参与者发出提交事务的指令。

若协调者收到不可提交的反馈,则向所有参与者发出回滚事务的指令。

例子:银行A向银行B转账

1. 准备阶段由交易中间件向双方银行系统发出预提交指令,银行A系统执行资金转出操作,银行B系统执行资金转入操作,但均不提交,等待交易中间件的指令。

2. 提交阶段分为两种情况:其一,交易中间件收到A、B的可提交反馈,则银行A和B发送提交指令;其二,交易中间件收到不可提交的反馈,则向银行A和B发送回滚指令,如下图所示。

优点:尽量保证了强一致性,但也并非完全的强一致性

缺点:预提交完成后参与者会锁定资源,直到提交或回滚才释放,对性能影响较大

(二)补偿事务(Try Confirm Cancel,TCC)

TCC 事务机制实际就是每一个业务操作都对应着一个确认和一个补偿操作,可分为三个处理阶段:Try(初始操作),Confirm(确认操作),Canel(取消操作)。

Try(初始操作)

  • 检测业务资源是否能够满足业务需求
  • 预留业务资源,即对所需的资源加锁

Confirm(确认操作)

Try阶段成功后执行Confirm阶段。

Canel(取消操作)

Cancel 阶段主要进行数据回滚和资源释放。

例子:银行A向银行B转账

Try阶段:协调者向转账双方银行系统发出预留业务资源的请求,双方系统分别对业务资源进行检查和锁定。

Commit阶段:Try阶段预留操作均成功,则向转账双方系统发出提交请求,双方系统使用Try阶段预留的业务资源执行资金转入和转出操作,若Commit失败则需要重试。

Cancel阶段:Try阶段预留操作出现失败情况,则向转账双方系统发出回滚请求,双方系统取消业务的执行,释放预留的业务资源,若Cancel失败则需要重试。

优点:按业务逻辑锁定部分资源,相比较2PC,能在一定程度上缓解性能问题

缺点:TCC与2PC有着类似的处理流程,是一种位于应用层的处理,需要业务逻辑支持,实现成本高

(三)本地消息表

本地消息表的解决方案最早在eBay的论文《Base: An Acid Alternative》提出,主要思想是将分布式事务通过本地消息的方式拆分成本地事务进行处理,即:

在进行业务操作的同时记录消息,并通过本地事务保证业务操作和消息记录的一致性,然后根据本地的消息表来保证分布式事务的BASE理论。

例子:银行A向银行B转账

  1. 银行A记录转账消息,并执行资金转出操作(这两个操作需要在同一个本地事务中执行)。
  2. 银行A定时扫描本地消息表,将未完成的消息发往银行B。
  3. 银行B接收消息后,首先,记录消息;其次,执行资金转入操作;最后,更新消息状态(这三个操作需要在同一个本地事务中执行)。
  4. 银行B通知银行A系统更新消息状态。

在这个例子中,还需要注意消息超时重试、幂等性等问题,这就需要在具体的业务场景中不同的实现方式来实现了。

优点:通过本地事务间接实现了最终一致性,实现相对简单

缺点:事务管理与业务处理耦合程度较高

(四)消息队列事务

RocketMQ支持事务消息,下面直接以银行A向银行B转账为例说明大致处理过程:

  1. 银行A向消息队列发送转账消息,消息状态为Prepared,此消息对消费者(银行B)不可见
  2. 消息发送成功后,银行A执行资金转出操作
  3. 银行A向消息队列发送确认消息
  4. 消息队列根据确认消息将转账消息状态设置为Commited,对消费者可见
  5. 银行B取出转账消息
  6. 银行B执行资金转入操作

注意:

步骤3操作失败,消息队列会定时扫描队列中的Prepared消息,询问消息发送方,由发送方决定重试或是回滚。

步骤5操作失败意味着消费者没有拿到队列中的消息,这种情况通常由网络超时引起,在这种情况下,消费者会不断尝试从队列取出消息。

步骤6操作失败意味着银行B的处理出现了异常,这时会根据RocketMQ的默认重试策略(重试16次,且重试间隔不断变长,最长为2H)或用户的设置进行重试,这里当然会存在一个问题,比如银行B账户被冻结,这时就需要通知银行A回滚数据,这个功能RocketMQ没有提供,这就需要自行实现了。

优点:不需依赖本地事务,RocketMQ给出了实现

缺点:数据回滚功能需要自行实现,实现难度大,其他主流消息队列不支持事务消息

(五)Sagas事务

Sagas事务的基本思想是将分布式系统中的事务分解为多个子事务和与子事务对应的补偿事务,当且仅当所有的子事务都进行了提交,Sagas事务才完成;如果其中一部分子事务执行失败,则必须对已提交的子事务进行补偿。

Sagas事务比较简单的一种形式是通过一个协调者协调各个子事务的执行和回滚,

例子:银行A向银行B转账

  1. 事务协调器按子事务顺序,分别向银行A和银行B发送业务处理请求。
  2. 银行A执行资金转出事务,失败则按子事务执行顺序逆序执行补偿事务。
  3. 银行B执行资金转入事务,失败则按子事务执行顺序逆序执行补偿事务。

Sagas事务总体来说提供了一种很简洁的事务管理思想,在具体实现上可以有很大差别,在后续的研究中也出现了许多的变种机制,很值得学习。

四、总结

通过本篇的学习,我们对分布式事务中的CAP定理、BASE理论以及经典的解决方案有了一定的了解。直到今天,分布式事务仍然是一个技术难题,没有任何一种解决方案能够完美解决所有分布式环境中的一致性问题,我们需要具体问题具体分析,根据业务场景和业务需要,选择和设计最适合的解决方案。

五、参考资料

本篇文章参考了多篇前人的优秀博客,一部分概念的介绍直接照搬来了,在此特别感谢博主的分享,参考资料链接如下:

从分布式一致性谈到CAP理论、BASE理论

聊聊分布式事务,再说说解决方案

分布式系统中数据库的事务如何处理?

分布式事务:不过是在一致性、吞吐量和复杂度之间,做一个选择

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值