微服务架构之分布式事务解决方案

Posted by Kaka Blog on April 24, 2019

事务的定义

事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元,组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。

简单地说,事务提供一种“要么什么都不做,要么做全套(All or Nothing)”机制。

什么是分布式事务?

分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。

本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

CAP原理和BASE原理

CAP原理

CAP 定理,又被叫作布鲁尔定理。

C (一致性): 对某个指定的客户端来说,读操作能返回最新的写操作。对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。

A (可用性): 非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回 50,而不是返回 40。

P (分区容错性): 当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。

BASE原理

BASEBasically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAPAP 的一个扩展。

基本可用: 分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。

软状态: 允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是 CAP 中的不一致。

最终一致: 最终一致是指经过一段时间后,所有节点数据都将会达到一致。

BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。

分布式事务解决方案

两阶段提交型(2PC)

两阶段型:就是分布式事务两阶段提交,对应技术上的XAJTA(java Transaction API)/JTS。 这是分布式环境下事务处理的典型模式。

准备阶段:

事务协调者(事务管理器)给每个参与者(资源管理器,通常指数据库)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redoundo日志,但不提交。

提交阶段:

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

  • 优点: 尽量保证了数据的强一致,实现成本较低,在各大主流数据库都有自己实现,对于 MySQL 是从 5.5 开始支持。
  • 缺点:
    • 单点问题: 事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候事务管理器宕机,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。
    • 同步阻塞: 在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。
    • 数据不一致: 在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据不一致性的现象。

Atomikos实现JTA/XA,产品分两个版本:

TransactionEssentials:开源的免费产品

ExtremeTransactions:上商业版,需要收费。

事务补偿型(TCC)

img

Try 阶段: 尝试执行,完成所有业务检查(一致性),预留必需业务资源(准隔离性)。

Confirm 阶段: 确认真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。

Cancel 阶段: 取消执行,释放 Try 阶段预留的业务资源,Cancel 操作满足幂等性。Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致。

TCC的开源框架有:Atomikostcc-transactionByteTcc支付宝GTS

应用场景:

我们通过用户下单使用余额+红包支付来看一下TCC事务的具体应用。

假设用户下单操作来自3个系统下单系统、资金账户系统、红包账户系统,下单成功需要同时调用资金账户服务和红包服务完成支付

假设购买商品1000元,使用账户红包200元,余额800元,确认支付。

  • Try操作
    • tryX 下单系统创建待支付订单
    • tryY 冻结账户红包200元
    • tryZ 冻结资金账户800元
  • Confirm操作
    • confirmX 订单更新为支付成功
    • confirmY 扣减账户红包200元
    • confirmZ 扣减资金账户800元
  • Cancel操作
    • cancelX 订单处理异常,资金红包退回,订单支付失败
    • cancelY 冻结红包失败,账户余额退回,订单支付失败
    • cancelZ 冻结余额失败,账户红包退回,订单支付失败

TCC与XA/JTA对比

  • XA是资源层面的分布式事务,通常都是在跨库的DB层面,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。
  • TCC是业务层面的分布式事务,本质就是一个应用层面的2PC,最终一致性,不会一直持有资源的锁。

参考