摘要:分布式事务架构设计旨在确保在多个分布式节点上执行的操作要么全部成功提交,要么全部回退,以维护数据的一致性和完整性。以下是几种常见的分布式事务架构设计方案:
分布式事务架构设计旨在确保在多个分布式节点上执行的操作要么全部成功提交,要么全部回退,以维护数据的一致性和完整性。以下是几种常见的分布式事务架构设计方案:
1. 两阶段提交(2PC)
原理:
准备阶段(Prepare):协调者向所有参与者发送 Prepare 消息,参与者接收到消息后,检查自身事务执行情况,如果可以提交,则将事务执行结果写入日志,并向协调者回复 Yes,表示准备好提交;如果无法提交,则回复 No。
提交阶段(Commit):如果协调者收到所有参与者的 Yes 回复,那么向所有参与者发送 Commit 消息,参与者接收到 Commit 消息后,正式提交事务;如果有任何一个参与者回复 No,或者在规定时间内没有收到所有参与者的回复,协调者向所有参与者发送 Rollback 消息,参与者回滚事务。
示例:假设有一个电商系统,涉及订单服务、库存服务和支付服务三个微服务。在一次购物流程中,订单服务创建订单,库存服务扣减库存,支付服务处理支付。协调者(可以是订单服务)发起两阶段提交。首先进入准备阶段,订单服务询问库存服务和支付服务是否可以提交事务,库存服务检查库存充足后回复 Yes,支付服务检查支付信息无误后也回复 Yes。接着进入提交阶段,订单服务向库存服务和支付服务发送 Commit 消息,两个服务正式提交事务,完成整个购物流程。
优缺点:
优点:原理简单,能够严格保证事务的原子性,即所有参与者要么全部提交,要么全部回滚。
缺点:性能开销大,尤其是在跨网络节点时,需要多次消息往返;存在单点故障问题,协调者一旦出现故障,可能导致整个事务无法继续进行;并且在提交阶段,如果部分参与者出现故障,可能导致数据不一致。
2. 三阶段提交(3PC)
原理:
CanCommit 阶段:协调者向参与者发送 CanCommit 消息,询问参与者是否可以进行事务提交。参与者检查自身资源和事务执行情况,如果可以提交,则回复 Yes,否则回复 No。
PreCommit 阶段:如果协调者收到所有参与者的 Yes 回复,向所有参与者发送 PreCommit 消息,参与者接收到消息后,将事务执行结果写入日志,但不正式提交事务,并向协调者回复 ACK。
DoCommit 阶段:协调者收到所有参与者的 ACK 回复后,向所有参与者发送 DoCommit 消息,参与者接收到消息后正式提交事务;如果在任何阶段有参与者回复 No 或者超时未收到所有参与者的回复,协调者发送 Abort 消息,参与者回滚事务。
示例:在一个分布式文件系统中,涉及文件存储节点 A、B、C。当进行一个文件的多节点同步更新操作时,协调者发起三阶段提交。在 CanCommit 阶段,询问三个节点是否可以更新文件,三个节点检查自身状态后都回复 Yes。接着进入 PreCommit 阶段,协调者向三个节点发送 PreCommit 消息,节点将更新操作写入日志并回复 ACK。最后进入 DoCommit 阶段,协调者发送 DoCommit 消息,三个节点正式更新文件。
优缺点:
优点:相比 2PC,3PC 减少了单点故障导致数据不一致的风险,在 PreCommit 阶段增加了缓冲,使得在协调者故障恢复后可以继续完成事务;并且在一定程度上提高了系统的并发性能。
缺点:仍然存在性能问题,消息往返次数更多;实现复杂度较高,需要处理更多的状态和异常情况。
3. 补偿事务(TCC - Try - Confirm - Cancel)
原理:
Try 阶段:业务逻辑的初步尝试执行,主要是对业务资源进行检查和预留,不真正执行业务操作。例如在一个分布式转账系统中,对于转出账户,Try 阶段只是检查账户余额是否足够,而不是真正扣除金额;对于转入账户,只是预留相应的额度。
Confirm 阶段:如果 Try 阶段所有参与者都成功,那么进入 Confirm 阶段,真正执行业务操作,如转出账户扣除相应金额,转入账户增加相应金额。
Cancel 阶段:如果 Try 阶段有任何一个参与者失败,或者在后续过程中出现问题,进入 Cancel 阶段,对 Try 阶段的操作进行回滚,释放预留的资源。
示例:在一个酒店预订系统中,涉及酒店预订服务、支付服务和会员积分服务。当用户预订酒店时,酒店预订服务的 Try 阶段检查酒店房间是否可预订并预留房间;支付服务的 Try 阶段检查用户支付能力并冻结相应金额;会员积分服务的 Try 阶段检查积分规则。如果三个服务的 Try 阶段都成功,进入 Confirm 阶段,酒店预订服务确认预订,支付服务完成支付,会员积分服务扣除或增加相应积分。如果任何一个 Try 阶段失败,进入 Cancel 阶段,酒店预订服务释放预留房间,支付服务解冻金额,会员积分服务恢复积分状态。
优缺点:
优点:对网络故障和节点故障的容忍度较高,因为每个参与者都有独立的回滚机制;性能相对较好,因为 Try 阶段可以快速完成资源检查和预留,减少了长时间锁定资源的情况。
缺点:开发成本较高,需要业务开发者为每个业务操作实现 Try、Confirm 和 Cancel 三个方法;对业务逻辑的侵入性较大,需要在业务代码中嵌入分布式事务处理逻辑。
4. 消息队列实现最终一致性
原理:利用消息队列异步处理事务,将一个分布式事务拆分成多个本地事务,并通过消息队列进行异步通信和协调。例如,在一个电商订单系统中,订单创建成功后,发送一条消息到消息队列,库存服务和物流服务监听该消息队列,接收到消息后分别执行扣减库存和安排发货的本地事务。虽然这些操作不是严格的原子性,但通过重试机制和补偿逻辑,可以保证最终数据的一致性。
示例:在一个社交平台中,用户发布一条动态,涉及动态存储服务和通知服务。当用户发布动态时,动态存储服务将动态信息保存到数据库,并发送一条消息到消息队列。通知服务监听消息队列,接收到消息后,向用户的粉丝发送通知。如果通知服务在处理过程中出现故障,消息队列可以提供重试机制,确保通知最终能够成功发送。
优缺点:
优点:性能较好,通过异步处理提高了系统的并发能力;对业务系统的侵入性较小,只需要在关键业务节点添加消息发送和接收逻辑;实现相对简单,适合对一致性要求不是特别严格的场景。
缺点:不能保证事务的强一致性,只能保证最终一致性;消息队列本身的可靠性和稳定性需要保证,否则可能导致消息丢失或重复消费,影响数据一致性。
5. Saga 模式
原理:Saga 模式将一个长事务分解为多个本地短事务,每个本地短事务都有对应的补偿事务。这些本地短事务按顺序依次执行,如果其中某个本地事务失败,Saga 会调用前面已执行事务的补偿事务,将系统状态恢复到事务开始前的状态。Saga 可以通过事件驱动或编排的方式进行协调。
示例:在一个跨国电商系统中,涉及多个国家的仓库和物流中心。当一个国际订单产生时,Saga 模式会依次执行各个国家仓库的库存检查和发货事务。如果某个国家的仓库发货失败,Saga 会调用前面已发货仓库的退货补偿事务,确保整个订单处理过程的一致性。
优缺点:
优点:适合处理复杂的长事务,通过将大事务分解为小事务,降低了事务处理的复杂度;具有较好的容错性,即使某个局部事务失败,也能通过补偿事务恢复系统状态。
缺点:需要为每个本地事务精心设计补偿事务,开发成本较高;事务执行过程中,如果中间某个事务失败,回滚可能比较复杂,需要处理好各个补偿事务之间的依赖关系。
来源:小小兔Ra