微服务分布式事务之LCN、TCC特点、事务补偿机制缘由以及设计重点 在亿级流量架构之分布式事务解决方案对比中, 已经简单阐明了从本机事务到分布式事务的演变过程, 文章的最后简单说明了TCC事务, 这儿将会深入了解TCC事务是原理, 以及理论支持, 最后会用Demo举例实现。 XA协议在上面提到的文章中, 分布式事务直接讲二阶段提交, 思维逻辑有些断层, 但是那毕竟是比较解决方案, 在这儿从理论上推导分布式事务的根基, 也就是为什么要二阶段提交。 在单体应用中, 往往由自己来保证事务的一致性, 但是分布式中, 涉及到跨网络调用就难以保证, 从理论上讲两台机器理论上无法达到一致的状态, 所以专门从服务角色上将事务操作抽象出一个服务用来协调事务, 叫做协调者, 或者说事务管理者。由全局事务管理器管理和协调的事务,可以跨越多个资源(如数据库或JMS队列)和进程。全局事务管理器一般使用 XA 二阶段提交协议与数据库进行交互。 而XA协议, 就是事务管理者与各个服务模块(也叫服务者、资源管理者)之间的通讯遵守的协议就是XA协议, 简单来说就是规范了接口, 这个协议由X/Open组织提出, 是分布式事务的规范。 XA规范主要定义了全局事务管理器(TM)和局部资源管理器(RM)之间的接口。除此之外, XA接口是双向的系统接口,在事务管理器 (TM)以及一个或多个资源管理器(RM)之 间形成通信桥梁,如上图。 二阶段提交协议二阶段协议,一句话说就是, 先进行一个复杂度低的询问操作, 看看各个服务模块(也叫参与者、资源管理者、RM)是否可以进行事务操作, 一方面检验网络是否通畅, 另一方面看看对应的资源是否被占用 , 如果可以得到的回应是所有的服务可以进行事务操作, 那么这时候再通知所有服务提交事务。详细的说, 二阶段提交(2PC:Two-Phase Commit), 该协议将一个分布式的事务过程拆分成两个阶段: 投票 和 事务提交 。为了让整个数据库集群能够正常的运行,该协议指定了一个 协调者(事务管理器) 单点,用于协调整个数据库集群各节点的运行。为了简化描述,我们将数据库集群中的各个节点称为 参与者(也叫服务者, 资源管理者) 。 第一阶段:投票该阶段的主要目的在于打探数据库集群中的各个参与者是否能够正常的执行事务,具体步骤如下:
第二阶段:事务提交在经过第一阶段协调者的询盘之后,各个参与者会回复自己事务的执行情况,这时候存在 3 种可能性:
对于第 1 种情况,协调者将向所有的参与者发出提交事务的通知,具体步骤如下:
除此之外, 还有2种情况, 囿于篇幅, 详情参考: 亿级流量架构之分布式事务思路及方法后面的二阶段提交协议 今天要聊的TCC就是二阶段提交的具体事务实现。 LCN详情参考:官网(中文版) 有了前面的XA协议以及二阶段提交的知识, 就不难理解LCN框架了, 这个框架可以理解成就是上面所说的协调者, 不生产事务, 只负责协调事务。5.0以后框架兼容了LCN、TCC、TXC三种事务模式。 LCN中各个字母依次代表:锁定事务单元(lock)、确认事务模块状态(confirm)、通知事务(notify)。 在一个分布式系统下存在多个模块协调来完成一次业务。那么就存在一次业务事务下可能横跨多种数据源节点的可能。TX-LCN目的是解决这样的问题。 例如存在服务模块A 、B、 C。A模块是mysql作为数据源的服务,B模块是基于redis作为数据源的服务,C模块是基于mongo作为数据源的服务。若需要解决他们的事务一致性就需要针对不同的节点采用不同的方案,并且统一协调完成分布式事务的处理。 在LCN中, 协调者称之为TxManager , 参与者称之为 TxClient, TxManager作为分布式事务的控制方, 事务发起方或者参与方都由TxClient端来控制决定。 时序图(来源官网): LCN核心步骤
TCC详情参考: Github(中文版) TCC事务机制相对于二阶段提交,其特征在于它不依赖资源管理器(RM)对XA协议的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务, 将事务分成 Try 和 Confirm/ Cancel两个阶段。 三种操作作用: Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。 整体流程如图 Try 从执行阶段来看,与传统事务机制(二阶段提交)中业务逻辑相同。但从业务角度来看,却不一样。TCC机制中的Try仅是一个初步操作,它和后续的确认一起才能真正构成一个完整的业务逻辑。TCC机制将传统事务机制(2PC)中的业务逻辑一分为二: 拆分后保留的部分为初步操作(Try); 而分离出的部分即为验证操作(Confirm/cancel),被延迟到事务提交阶段执行。 三阶段主要特点:
TCC补偿机制在很多情况下,我们是无法做到强一致的 ACID 的。特别是我们需要跨多个系统的时候,而且这些系统还不是由一个公司所提供的。比如,在我们的日常生活中,我们经常会遇到这样的情况,就是要找很多方协调很多事,而且要保证我们每一件事都成功,否则整件事就做不到。 参考 http://www./article/6556 比如,要出门旅游, 我们需要干这么几件事。 第一,向公司请假,拿到相应的假期; 第二,订飞机票或是火车票; 第三,订酒店; 第四,租车。 这四件事中,前三件必需完全成功,我们才能出行,而第四件事只是一个锦上添花的事,但第四件事一旦确定,那么也会成为整个事务的一部分。这些事都是要向不同的组织或系统请求。我们可以并行地做这些事,而如果某个事有变化,其它的事都会跟着出现一些变化。 设想下面的几种情况。
从人类的实际生活当中,我们可以看出,上述的这些情况都是天天在发生的事情。所以,我们的分布式系统也是一样的,也是需要处理这样的事情——就是当条件不满足,或是有变化的时候,需要从业务上做相应的整体事务的补偿。 对于业务补偿来说,首先需要将服务做成幂等性的,如果一个事务失败了或是超时了,我们需要不断地重试,努力地达到最终我们想要的状态。然后,如果我们不能达到这个我们想要的状态,我们需要把整个状态恢复到之前的状态。另外,如果有变化的请求,我们需要启动整个事务的业务更新机制。 业务补偿机制特点由上可知,一个好的业务补偿机制需要做到下面这几点。
其实,在纯技术的世界里也有这样的事。比如,线上运维系统需要发布一个新的服务或是对一个已有的服务进行水平扩展,我们需要先找到相应的机器,然后初始化环境,再部署上应用,再做相应的健康检查,最后接入流量。这一系列的动作都要完全成功,所以,我们的部署系统就需要管理好整个过程和相关的运行状态。 业务补偿的设计重点业务补偿主要做两件事。
所以,下面是几个重点。
站在巨人的肩膀上 |
|