加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

分布式事务的实现原理详解

发布时间:2019-08-19 21:37:05 所属栏目:MySql教程 来源:进击的IT程序员
导读:副标题#e# 事务是数据库系统中非常有趣也非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全不执行;在 SOA 与微服务架构大行其道的今天,在分布式的多个服务中保证业务的一致性就需要我们实

当我们使用 Saga 模式开发分布式事务时,有两种协调不同服务的方式,一种是协同(Choreography),另一种是编排(Orchestration):

分布式事务的实现原理详解

saga-pattern

如果对于一个分布式事务,我们采用协同的方式进行开发,每一个本地的事务都会触发一个其他服务中的本地事务的执行,也就是说事务的执行过程是一个流的形式进行的:

分布式事务的实现原理详解

saga-pattern-choreography

当我们选择使用协同的方式处理事务时,服务之间的通信其实就是通过事件进行的,每一个本的事务最终都会向服务的下游发送一个新的事件,既可以是消息队列中的消息,也可以是 RPC 的请求,只是下游提供的接口需要保证幂等和重入。

除此之外,通过协同方式创建的分布式事务其实并没有明显的中心化节点,多个服务参与者之间的交互协议要从全局来定义,每个服务能够处理以及发送的事件和接口都需要进行比较严谨的设计,尽可能提供抽象程度高的事件或者接口,这样各个服务才能实现自治并重用已有的代码和逻辑。

如果我们不想使用协同的方式对分布式事务进行处理,那么也可以选择编排的方式实现分布式事务,编排的方式引入了中心化的协调器节点,我们通过一个 Saga 对象来追踪所有的子任务的调用情况,根据任务的调用情况决定是否需要调用对应的补偿方案,并在网络请求出现超时时进行重试:

分布式事务的实现原理详解

saga-pattern-orchestration

在这里我们就引入了一个中心化的『协调器』,它会保存当前分布式事务进行到底的状态,并根据情况对事务进行回滚或者提交操作,在服务编排的过程中,我们是从协调者本身触发考虑整个事务的执行过程的,相对于协同的方式,编排实现的过程相对来说更为简单。

协同与编排其实是两种思路截然相反的模式,前者强调各个服务的自治与去中心化,后者需要一个中心化的组件对事务执行的过程进行统一的管理,两者的优缺点其实就是中心化与去中心化的优缺点,中心化的方案往往都会造就一个『上帝服务』,其中包含了非常多组织与集成其他节点的工作,也会有单点故障的问题,而去中心化的方案就会带来管理以及调试上的不便,当我们需要追踪一个业务的执行过程时就需要跨越多个服务进行,增加了维护的成本。

下游约束

当我们选择使用 Saga 对分布式事务进行开发时,会对分布式事务的参与者有一定的约束,每一个事务的参与者都需要保证:

提供接口和补偿副作用的接口;

接口支持重入并通过全局唯一的 ID 保证幂等;

这样我们就能够保证一个长事务能够在网络通信发生超时时进行重试,同时在需要对事务进行回滚时调用回滚接口达到我们的目的。

小结

Saga 这种模式其实完全放弃了同时满足事务四大基本特性 ACID 的想法,而是选择降低实现分布式事务的难度并减少资源同步以及锁定带来的问题,选择实现 BASE(Basic Availability, Soft, Eventual consistency) 事务,达到业务上的基本可用以及最终一致性,在绝大多数的业务场景中,实现最终一致性就能够基本满足业务的全部需求,极端场景下还是应该选择两阶段提交或者干脆放弃分布式事务这种易错的实现方式,转而使用单机中的数据库事务来解决。

消息服务

分布式事务带来复杂度的原因其实就是由于各个模块之间的通信不稳定,当我们发出一个网络请求时,可能的返回结果是成功、失败或者超时。

分布式事务的实现原理详解

network-communication

网络无论是返回成功还是失败其实都是一个确定的结果,当网络请求超时的时候其实非常不好处理,在这时调用方并不能确定这一次请求是否送达而且不会知道请求的结果,但是消息服务可以保证某条信息一定会送达到调用方;大多数消息服务都会提供两种不同的 QoS,也就是服务的等级。

分布式事务的实现原理详解

message-delivery-qos

最常见的两种服务等级就是 At-Most-Once 和 At-Least-Once,前者能够保证发送方不对接收方是否能收到消息作保证,消息要么会被投递一次,要么不会被投递,这其实跟一次普通的网络请求没有太多的区别;At-Least-Once 能够解决消息投递失败的问题,它要求发送者检查投递的结果,并在失败或者超时时重新对消息进行投递,发送者会持续对消息进行推送,直到接受者确认消息已经被收到,相比于 At-Most-Once,At-Least-Once 因为能够确保消息的投递会被更多人使用。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读