分布式操作系统
在如今分布式盛行的时代,分布式事务永远都是绕不开的一个话题,今天就重点详解分布式事务相关的一致性,以及分布式事务的实战解决方案@mikechen
为什么需要分布式事务
在分布式系统中,需要使用分布式事务来解决以下问题:
1.数据一致性问题
当多个服务或系统同时修改同一份数据时,需要确保数据的一致性,避免数据的不一致性。
2.故障恢复问题
在分布式系统中,任何一个服务或系统的故障都可能导致整个系统的故障。
因此,在进行分布式事务操作时,需要确保在任何情况下都能够恢复数据。
3.并发控制问题
在分布式系统中,多个服务或系统同时对同一份数据进行操作,需要通过并发控制来避免数据的冲突和错误。
因此,为了保证分布式系统中数据的一致性和可靠性,需要使用分布式事务来管理事务操作。
分布式事务典型场景
举一个最经典的例子,比如:阿里的淘宝、天猫等网站随着访问量越来越大,数据库需要拆分,需要按照业务为单位来进行拆分。
比如:按照商品、订单、用户等业务为单位进行数据库拆分。
如下图所示:
比如:我的业务里要实现一个:要完成购买商品,下订单这个简单的流程。
这个时候,就需要横跨多个数据库,比如:会涉及到:用户、订单、商品、库存等多个数据库,而这些数据库又是分布到不同的服务器上。
这就会涉及到分布式事务了,从本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。
以前在单个应用的简单场景,变成分布式以后,就没有这么简单了,需要考虑分布式事务了。
分布式事务的解决方案
谈完了分布式事务的来源,这里我再谈下分布式事务的具体解决方案@mikechen
如下图所示:
基于XA协议的两阶段提交 2PC
XA协议的核心是“两阶段提交”(Two-Phase Commit,2PC)协议。
在2PC协议中,分布式事务被分为两个阶段,如下图所示:
1.准备阶段(Prepare Phase)
协调者(事务管理器)向所有参与者(资源管理器)发出prepare请求,参与者执行事务并将undo和redo信息记录在本地事务日志中。如果所有参与者都成功执行了事务并准备提交,则参与者向协调者发送prepared响应,否则发送abort响应。
2.提交阶段(Commit Phase)
如果协调者接收到了所有参与者的prepared响应,则向所有参与者发送commit请求,参与者执行事务提交,并将完成状态写入本地日志中。如果参与者成功提交,则向协调者发送ack响应,否则发送nack响应。
优缺点
两阶段该方案通过协调者和参与者之间的协作来确保所有参与者都执行了事务,并且在所有参与者都准备好提交之后再进行提交。
这种方案具有简单、通用、可靠等优点,但也存在单点故障、性能问题等缺点。
2.事务补偿TCC模式
TCC方案其实是两阶段提交的一种改进,将整个业务逻辑的每个分支显式的分成了Try、Confirm、Cancel三个操作。
如下图所示:
TCC模式的执行过程可以分为以下三个步骤:
1.尝试(Try)
事务参与者在执行事务之前,首先尝试执行事务,并在本地预留资源。在这个阶段,事务参与者需要检查所有必要的条件是否满足,以及是否有足够的资源来执行事务。如果条件满足,事务参与者会将执行结果缓存在本地,等待后续的确认操作。
2.确认(Confirm)
在所有事务参与者都执行完尝试阶段之后,协调者向所有事务参与者发出确认请求,以执行真正的事务提交。在这个阶段,事务参与者需要将缓存的执行结果提交到数据存储中,并释放之前预留的资源。
3.取消(Cancel)
如果在执行确认阶段之前,任何一个事务参与者失败或超时,协调者会向所有事务参与者发出取消请求,以回滚之前执行的所有操作。在这个阶段,事务参与者需要撤销之前预留的资源,并回滚任何之前执行的操作。
优缺点
TCC模式相比于传统的2PC模式,具有更高的可靠性和兼容性,缺点是:对代码有侵入性,增加了代码的复杂度和实现难度。
3.消息队列最终一致性方案
分布式事务消息队列最终一致性方案是一种利用消息队列来实现分布式事务的解决方案,它采用异步提交和最终一致性的方式来保证分布式事务的一致性。
如下图所示:
在这个方案中,消息队列起到了一个缓冲和传输的作用,通过异步提交和最终一致性的方式来实现了分布式事务的一致性。
由于消息队列的高可用性和可靠性,该方案也具有很高的可靠性和可伸缩性。
案例
RocketMQ RabbitMQ等均可实现,RocketMQ 还有专门的事务型消息,新版的kafka也有。
以上
更多分布式架构系列、阿里架构师进阶系列,请查看以下文章:
阿里架构师进阶从0到1全部合集(建议收藏)