释义
特指多个服务同时访问多个数据源的事务处理机制。
CAP定理
内容
在一个分布式系统中,涉及共享数据问题时,以下三个特性至多同时满足两个:
- 一致性 (Consistency): 数据在任何时刻、任何分布式节点所看到的,都是符合预期的。
- 可用性 (Availability): 代表系统不间断提供服务的能力,主要关注可靠性和可维护性两个指标,前者使用平均无故障时间MTBF度量,后者使用平均可修复时间MTTR度量。可用性可表征为二者的比值 ,如99.9999%可用则代表平均年故障修复时间32秒。
- 分区容忍性 (Partition Tolerance): 分布式环境中部分节点因网络原因彼此失联后,即与其他节点形成“网络分区”时,系统仍能正确地提供服务的能力。
取舍
- 放弃分区容忍性:假设节点之间通信永远可靠,这和用网络来共享数据冲突。典型例子是关系数据库集群,选择共享磁盘的方式来避免出现网络分区,但并不能称作分布式系统。分区容忍性本质上是分布式网络的天然属性。
- 放弃可用性:假设一旦网络发生分区,节点间的信息同步时间可以无限制地延长。此时退化为一个系统使用多个数据源的场景。仅用于对数据质量要求高的场合,如HBase系统也是CP(放弃可用性)系统,RegionServer宕机后,这个RegionServer持有的所有键值范围离线,直至数据恢复过程完毕,耗时无法估量。通常是选用分布式的目的,除非是宁可中断也不能出错的金融服务,否则无法接受节点增多反而降低可用性。
- 放弃一致性:即一旦发生分区,节点间提供的数据可能不一致。目前主流NoSQL库和支持分布式的缓存框架都是AP(放弃一致性)系统。
最终一致性
对于没有被另外操作所改变的数据的读取,最终都能获取已更新的数据,但不完全保证立即获取已更新的数据。面向最终一致性的算法也被称为“乐观复制算法”。
BASE定理
- 基本可用性(Basically Available)、软状态/柔性事务(Soft State)和最终一致性(Eventually Consistent)
- BASE理论面向大规模分布式系统,牺牲强一致性换取高可用性。而ACID理论是强一致性模型,传统数据库设计理念。
- 二者是截然相反的设计哲学,系统中不同组件对一致性和可用性的要求是不一样的,因此二者通常也结合使用。
柔性事务
可靠事件队列
- 依靠持续重试来保证可靠性,TCP中未收到ACK应答自动重新发包也是类似的道理。
- 最大努力一次提交:指的就是将最有可能出错的业务以本地事务的方式完成后,采用不断重试的方式(不限于消息系统)来促使同一个分布式事务中的其他关联业务全部完成。
- 缺点:没有任何隔离性,可能会出现超售等问题。
TCC事务
- 强隔离性的分布式事务,业务侵入式较强,要求业务处理必须拆分为“预留业务资源”和“确认/释放消费资源”两个子过程。
- 执行流程:
- Try: 尝试执行阶段,完成所有业务可执行性的检查(保障一致性),并且预留好全部需用到的业务资源(保障隔离性)。
- Confirm: 确认执行阶段,不进行任何业务检查,直接使用 Try 阶段准备的资源来完成业务处理。Confirm 阶段可能会重复执行,因此本阶段所执行的操作需要具备幂等性。
- Cancel: 取消执行阶段,释放 Try 阶段预留的业务资源。Cancel 阶段可能会重复执行,也需要满足幂等性。
- 位于用户代码层面,灵活性较高,可以设计资源锁定的粒度。同时业务执行阶段只操作预留资源,几乎不涉及锁和资源的竞争,具有性能潜力,在柔性事务中性能偏高。
- 开发成本和替换成本更高,业务侵入性强。
- 通常基于分布式事务中间件(如阿里开源Seata)实现,而非纯靠裸编码。
SAGA事务
- TCC事务业务侵入性高,而如用户、商家的账号余额通常由银行管理,权限和数据结构难以随心所欲自定义,无法在Try阶段完成款项冻结、解冻等操作。
- 执行流程:
- 将整个分布式事务分解,每个子事务都是或能被视作原子行为,连续顺序提交子事务和分布式事务正常提交对数据影响等价(最终一致性)。
- 为每个子事务设计对应补偿动作。
- 子事务及其补偿动作具备幂等性。
- 子事务及其补偿动作满足交换律,即二者谁优先执行都是同样结果。
- 子事务对应的补偿动作必须能够成功提交,即不考虑补偿动作提交失败被回滚(如出现则持续重试直至成功或人工介入)。
- 如事务未能顺利完成,需要采取恢复策略。
- 正向恢复:对提交失败的子事务 一直重试,直至成功(最大努力交付),如从银行账户扣款后就一定要正常给发货。
- 正向恢复执行模式:(失败),(重试)。
- 反向恢复:如果 事务提交失败,则一直执行 对 进行补偿,直至成功为止(最大努力交付)。这里要求 必须(在持续重试后)执行成功。
- 反向恢复执行模式:(失败),(补偿)。
- 正向恢复:对提交失败的子事务 一直重试,直至成功(最大努力交付),如从银行账户扣款后就一定要正常给发货。
- 补偿操作通常比冻结等操作容易实现,无法撤销用户转帐,但可以由系统将货款转回用户账上作为补偿措施。
- 必须设计成与数据库类似的日志机制(被称为 SAGA Log)以保证系统恢复后可以追踪到子事务的执行情况,譬如执行至哪一步或者补偿至哪一步了。