分布式事务相关概念及解决方案的总结

笔者申明:以下是为了学习总结,内容都是摘抄于网上博客,笔者只做了内容排版等。

1. 概念要清楚

分布式事务(DistributedTransaction DT ):分布式事务顾名思义就是在分布式环境下运行的事务,对于分布式事务来说,事务的每个操作步骤是运行在不同机器上的服务的。分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)

事务补偿机制:在事务链中的任何一个正向事务操作, 都必须存在一个完全符合回滚规则的可逆事务。

CAP理论:CAP(Consistency, Availability, Partition Tolerance), 阐述了一个分布式系统的三个主要方面, 只能同时择其二进行实现. 常见的有CP系统, AP系统.

BASE(Basicallyavaliable, soft state, eventually consistent): 是分布式事务实现的一种理论标准.例如订单的状态:待支付、待付款等.

ACID:指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transactionprocessing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。

幂等性:简单的说, 业务操作支持重试, 不会产生不利影响. 常见的实现方式: 为消息额外增加唯一ID.

2. 柔性事务vs刚性事务

刚性事务:是指严格遵循ACID原则的事务, 例如单机环境下的数据库事务.

柔性事务:是指遵循BASE理论的事务, 通常用在分布式环境中, 常见的实现方式有: 两阶段提交(2PC), TCC补偿型提交, 基于消息的异步确保型, 最大努力通知型.

通常对本地事务采用刚性事务,分布式事务使用柔性事务。
3. 最佳实战

A:如果业务场景需要强一致性, 那么尽量避免将它们放在不同服务中, 也就是尽量使用本地事务, 避免使用强一致性的分布式事务.

B :如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.

C: 如果业务场景需要强一致性, 并且只能够进行分布式服务部署, 那么最好是使用TCC方案而不是2PC方案来解决.

3.1 两阶段提交(2PC)

两阶段提交(Two Phase Commit, 2PC), 具有强一致性, 是CP系统的一种典型实现.

两阶段提交, 常见的标准是XA, JTA等. 例如Oracle的数据库支持XA.

下图是两阶段提交的示意图:

图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示

图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示。

缺点:

1、两阶段提交中的第二阶段, 协调者需要等待所有参与者发出yes请求, 或者一个参与者发出no请求后, 才能执行提交或者中断操作. 这会造成长时间同时锁住多个资源, 造成性能瓶颈, 如果参与者有一个耗时长的操作, 性能损耗会更明显.

2、 实现复杂, 不利于系统的扩展, 不推荐.

3.2 TCC (Try-Confirm-Cancle)

TCC,是基于补偿型事务的AP系统的一种实现, 具有最终一致性.


下面以客户购买商品时的付款操作为例进行讲解:

 Try:

    完成所有的业务检查(一致性),预留必须业务资源(准隔离性);

    体现在本例中, 就是确认客户账户余额足够支付(一致性), 锁住客户账户, 商户账户(准隔离性).

 Confirm:

    使用Try阶段预留的业务资源执行业务(业务操作必须是幂等的), 如果执行出现异常, 要进行重试.

    在这里就是执行客户账户扣款,商户账户入账操作.

 Cancle:

    释放Try阶段预留的业务资源, 在这里就是释放客户账户和商户账户的锁;

    如果任一子业务在Confirm阶段有操作无法执行成功, 会造成对业务活动管理器的响应超时, 此时要对其他业务执行补偿性事务. 如果补偿操作执行也出现异常, 必须进行重试, 若实在无法执行成功, 则事务管理器必须能够感知到失败的操作, 进行log(用于事后人工进行补偿性事务操作或者交由中间件接管在之后进行补偿性事务操作).

优点:对比与前面提到的两阶段提交法, 有两大优势

1、TCC能够对分布式事务中的各个资源进行分别锁定, 分别提交与释放, 例如, 假设有AB两个操作, 假设A操作耗时短, 那么A就能较快的完成自身的try-confirm-cancel流程, 释放资源. 无需等待B操作. 如果事后出现问题, 追加执行补偿性事务即可.

2、 TCC是绑定在各个子业务上的(除了cancle中的全局回滚操作), 也就是各服务之间可以在一定程度上”异步并行”执行.

注意事项:

 1、事务管理器(协调器)这个节点必须以带同步复制语义的高可用集群(HAC)方式部署.

 2、事务管理器(协调器)还需要使用多数派算法来避免集群发生脑裂问题.

适用场景

严格一致性、执行时间短、实时性要求高
附:

集群的脑裂:通常是发生在集群中部分节点之间不可达而引起的(或者因为节点请求压力较大,导致其他节点与该节点的心跳检测不可用)。当上述情况发生时,不同分裂的小集群会自主的选择出master节点,造成原本的集群会同时存在多个master节点。

3.3 异步确保型

通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响.

这个方案真正实现了两个服务的解耦, 解耦的关键就是异步消息补偿性事务.

这里以一个例子作为讲解:


执行步骤如下:

  1. MQ发送方发送远程事务消息到MQ Server;
  2. MQ Server给予响应, 表明事务消息已成功到达MQ Server.
  3. MQ发送方Commit本地事务.
  4. 若本地事务Commit成功, 则通知MQ Server允许对应事务消息被消费; 若本地事务失败, 则通知MQ Server对应事务消息应被丢弃.
  5. MQ发送方超时未对MQ Server作出本地事务执行状态的反馈, 那么需要MQ ServferMQ发送方主动回查事务状态, 以决定事务消息是否能被消费.
  6. 当得知本地事务执行成功时, MQ Server允许MQ订阅方消费本条事务消息.

需要额外说明的一点, 就是事务消息投递到MQ订阅方后, 并不一定能够成功执行. 需要MQ订阅方主动给予消费反馈(ack)

1、如果MQ订阅方执行远程事务成功, 则给予消费成功的ack, 那么MQ Server可以安全将事务消息移除;

2、如果执行失败, MQ Server需要对消息重新投递, 直至消费成功.

注意事项:

1、  消息中间件在系统中扮演一个重要的角色, 所有的事务消息都需要通过它来传达, 所以消息中间件也需要支持HAC 来确保事务消息不丢失.

2、根据业务逻辑的具体实现不同,还可能需要对消息中间件增加消息不重复, 不乱序等其它要求.

适用场景:

1、  执行周期较长

2、实时性要求不高

例如

1、  跨行转账/汇款业务(两个服务分别在不同的银行中)

2、  退货/退款业务

3、财务, 账单统计业务(先发送到消息中间件, 然后进行批量记账)

3.4 努力最大通知型

这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不同的一点是, 在消息由MQ Server投递到消费者之后, 允许在达到最大重试次数之后正常结束事务.

适用场景

交易结果消息的通知等

小结

不管是同步事务中的事务管理器(协调者), 还是异步事务中使用的消息中间件,若要达到一致性保证,都需要使用带有同步复制语义的 HAC 提供的高可用和高可靠特性,这些都是以性能为代价的,无疑成为了SOA 架构中的典型性能瓶颈之一.

附:集群软件的分类:

一般来讲,集群软件根据侧重的方向和试图解决的问题,分为三大类:高性能集群(High performance clusterHPC)、负载均衡集群(Loadbalance cluster LBC),高可用性集群(High availability clusterHAC

             名称

               解释

高性能集群(High performance clusterHPC

利用一个集群中的多台机器共同完成同一件任务,使得完成任务的速度和可靠性都远远高于单机运行的效果。弥补了单机性能上的不足。该集群在天气预报、环境监控等数据量大,计算复杂的环境中应用比较多

负载均衡集群(Load balance cluster LBC

利用一个集群中的多台单机,完成许多并行的小的工作。一般情况下,如果一个应用使用的人多了,那么用户请求的响应时间就会增大,机器的性能也会受到影响,如果使用负载均衡集群,那么集群中任意一台机器都能响应用户的请求,这样集群就会在用户发出服务请求之后,选择当时负载最小,能够提供最好的服务的这台机器来接受请求并相应,这样就可用用集群来增加系统的可用性和稳定性。这类集群在网站中使用较多

高可用性集群(High availability clusterHAC

利用集群中系统 的冗余,当系统中某台机器发生损坏的时候,其他后备的机器可以迅速的接替它来启动服务,等待故障机的维修和返回。最大限度的保证集群中服务的可用性。这类系统一般在银行,电信服务这类对系统可靠性有高的要求的领域有着广泛的应用

猜你喜欢

转载自blog.csdn.net/lyitit/article/details/80809625