文/中国人民银行清算总中心lqdlq
分布式系统
计算机科学理论中的CAP定理指出,分布式系统的一致性、可用性、分区容错性只满足三者中的两个。 架构师在分布式系统的APP设计中,在遇到一致性和可用性问题时,会直接影响用户体验和客户流失,因此经常选择可用性。 因此,分布式系统的一致性问题成为分布式系统领域探索的热门问题。
一提到分布式系统的一致性问题,就会涉及到事务。 事务处理Rransaction )是具有原子性Atomicity )、一致性)、隔离性Isolation )、持续性)等属性特性) ACID的一系列相关操作。
事务的ACID属性中的一致性和CAP定理的一致性有差异。 事务一致性是事务无法破坏数据库的规则,例如数据库键值是唯一的。 如果同时执行许多事务,则与按某个顺序执行的结果一样,数据库的键值的唯一性不会受到破坏。 CAP定理的一致性意味着分布式环境下所有节点获得的最新数据副本相同。 如果在分布式环境中同时执行每个节点的事务,则每个节点都可以获得数据的副本,这与按某个顺序执行的情况相同。 因此,事务在ACID属性中的一致性可能与分布式环境中的事务不一致。 CAP定理中提到的一致性是分布式环境下的一致性,是ACID一致性更严格的子集。
在多个开放系统之间执行的事务被称为分布式事务。 X/Open分布式事务处理模型X/Open XA )是分布式事务管理的事实标准,XA使用两阶段提交使事务中的所有参与者都可以提交或回滚,从而实现分布式事务处理实现了CAP定理中提到的一致性问题。
XA协议适合微服务技术体系结构吗? 让我们来看看微服务体系结构的特点。
微服务架构
知名架构师Adrian Cockcroft将微服务体系结构定义为面向服务的体系结构,由具有松散耦合和边界上下文的元素组成。 这里的边界上下文被理解为可以由通用接口定义语言IDL )定义的服务接口、服务、服务接口和接口间通信构成微服务的体系结构微服务体系结构以服务间的松散耦合、独立配置、技术的独立发展、快速可持续的交付、良好的容错性和重用性等,近年来在分布式系统应用技术体系结构的选择方面受到了更多的关注。
由于微服务架构以服务间的松散耦合为显著特征,所以两个阶段提出的每个操作都需要服务同时在线协商,服务间的耦合性很大。 因此,基于两阶段提交的XA协议的分布式事务管理机制不适合微服务架构的事务管理。 此外,XA协议的并行协商特征还会降低整个系统的可用性和系统性能。
实现原理
目前,Sagas是一种在微服务架构中管理多个服务数据操作,保持数据一致性,符合微服务架构特点的分布式事务管理解决方案。 实际上,我们使用补偿性交易作为处理漫长交易的方法。 将一个较长的交易分为多个子交易,各交易Ti对应于补偿交易Ci。 如果交易Tn 1失败,则长交易的执行顺序为T1…Tn、Cn…C1,取消通过执行罚款交易而提交的各个子交易,中止长交易。 当然,对数据库的读取操作不需要补偿事务。
Sagas中的每个子事务Ti都是本地事务,具有ACID属性。 由于Sagas可能会看到其他Sagas的部分执行结果,因此Sagas缺乏隔离性。 Sagas作为一个较长的交易序列,整体上具有ACD属性。
事务的独立性分为多个级别,包括未提交的读取、已提交的读取、可重复的读取和序列化。 缺乏隔离性会导致脏引线等。 由于Sagas缺乏隔离性,需要追加应对措施,如通过追加语义锁等对策,可以保证因缺乏隔离性而导致的一致性问题等。
下面,使用简化的转账业务,分析基于异步通信方式的事件自动存储开源架构分布式事务管理的实现方式和数据完整性保障机制。
分布式事务管理机制分析
简化的转账业务。 服务atransreqservice )是转账请求管理服务,服务b ) BTransDealService )是转账处理服务,两个微服务在不同的网络节点上运行,分别是同一数据库。 当服务a接收到来自顾客的转账请求时,在数据库中记录转账请求,通知服务b进行转账处理,并根据接收到的返还结果更新本地转账状态。 服务b接收呼叫申请,完成转账业务处理,更新数据库账户信息,将处理结果返回给服务a。
Eventuate Tram框架是一个用Sagas方法解决微服务分布式系统数据完整性管理问题的平台。 提供了基于事件消息的事件组织模式和基于命令消息的核心协调员的命令协调模式两种模式。 这两种模式都支持基于异步消息的通信方法,可以使用或不使用消息代理。 这里用消息代理的方式进行分析。
1 .事件组织模式。 事件组织,如其名,由组织了分散事务的Sagas序列进行管理。 事件组织模式支持事件消息。 以简
化的转账业务为例,事件编排实现过程如下。
(1)服务A接收转账请求,记录数据库表,并将其设置为pengding状态或加语义锁,同时发布事件记录插入消息表。
(2)数据库日志记录了插入消息表的相应操作,CDC服务读取和消息插入记录有关的数据库日志,并将事件消息记录发送给消息代理。
(3)服务B获取消息,进行资金结算并发布成功或失败的事件消息记录插入消息表。
(4)CDC服务读取和插入事件消息记录有关的数据库日志,并将消息记录发送给消息代理。
(5)服务A读取事件消息并更新转账pending状态为成功 / 失败。从而保证了数据的一致性。
这里数据库更新操作和事件发布作为一个事务,具有ACID事务属性,这由Eventuate Tram框架保证。这个过程是一个利用Sagas补偿事务来进行数据一致性管理的过程,第(5)步是对第(1)步转账请求的补偿。可以看出,Saga的补偿交易不像数据库回滚交易那样,好像什么都没发生,补偿交易是对之前的操作做了一次类似冲正的处理。由于Sagas缺乏隔离性,通过设置pengding状态,当有其他Sagas需要读取转账请求数据时,知道它处于一个中间状态。
2.命令协调器模式。命令协调器模式支持命令消息,有一个核心协调器进行分布式事务的集中管理。
下面介绍Eventuate Tram Sagas协调器的工作原理。微服务定义Saga序列,通过调用SagaManager的接口SimpleSaga创建Saga定义,即 Sagadefinition,实际上相当于实例化了一个Saga协调器。实例化内容包括设置交易Pengding状态、唤醒服务B、发布命令、读取回执并根据回执设置交易结果等保障服务有效的逻辑内容。这里的Eventuate Tram框架是保障对于数据库操作处理和命令消息发布处理作为一个事务处理机制。
以简化的转账业务为例,命令协调器的实现过程如下。
(1)服务A接受转账请求,记录转账请求并设置为pending状态。
(2)服务A实例化Saga来协调转账。
(3)Saga协调器发送转账命令给服务B。
(4)服务B接收到命令进行转账操作,并将转账结果以命令回复。
(5)Saga协调器接收到回复命令,并发送处理成功或失败命令给服务A。
(6)服务A接收命令进行更新转账状态。
上述实现步骤中,服务A实例化Saga协调器、设置转账状态,以及服务A和服务B发送和接收转账命令均是通过Eventuate Tram Sagas完 成。利用Eventuate Tram框架,CDC服务读取和消息插入记录有关的数据库日志,并将命令消息记录发送给消息代理,保证数据库操作和命令消息在一个本地事务中处理。
通过上述两种实现方式看,基于Sagas的分布式事务管理机制的正确性不取决于是否预先序列化或补偿事务处理,而是取决于事务序列化和补偿之后,对数据库状态的最终影响是否等效。经过补偿后,数据库最终是否会在与子事务从未执行过的相同的地方有相同的结果,最终影响主要是指系统整体外部效果。这里注意区分 Eventuate Tram Sagas和Eventuate Tram框架。事件编排模式利用了消息代理和 Eventuate Tram 框架。命令协调模式利用了消息代理、Eventuate Tram框架和 Eventuate Tram Sagas框架。
总 结
由于微服务架构间服务松耦合的特征,XA协议并不适合微服务架构,基于异步方式的Sagas架构更贴合微服务技术架构发展方向。架构师可根据自身技术储备选择基于同步的实现方式还是异步的实现方式。同步调用简单但会降低系统整体可用性,异步方式需要一些消息或消息代理知识,但系统整体可用性高。同时,建议正确对待单体架构和微服务架构。软件工程从来就没有银弹,架构总是在特定需求和组织框架下取舍。如果利用微服务架构的技术,采用单体架构的设计思想失去了微服务架构的技术意义,不仅增加了系统的架构复杂度,又没有享用到微服务架构带来的便利。