分布式事务
BASE
解释
BASE是对CAP中一致性和可用性权衡结果,核心是无法达到强一致性,能够达到强一致性eventual consistency
实例
-
大型分布式系统
-
关系型数据库
- 主备数据库
- 同步时存在延迟
- 同步时出现异常,数据不一致。重试或者人工解决,达到最终一致性
- 主备数据库
组成
- Basically Available基本不可用
- 响应时间损失
- 百度0.5变为1.2s
- 功能上损失
- 电商大促销,部分消费者引导到一个降级页面
- 响应时间损失
- Soft state软状态
- 允许系统数据存在中间状态,即允许不同节点副本数据同步时存在延时
- Eventually Consistent最终一致性
- 系统中所有副本,经过一段时间达到一致的状态,不需要实时保持系统数据的强一致
- 影响因素
- 网络延迟
- 系统负载
- 数据复制方案
- 分类
- Causal consistency因果一致性
- 线程A将结果告诉线程B,线程B能够根据最新数据操作,无关线程C没有限制
- Read your write读己之所写
- 线程A更新后,操作的是最新值,特殊Causal consistency
- Session consistency会话一致性
- 同一会话中操作的都是最新数据
- Monotonic read consistency单调读一致性
- 一个线程读取数据后,系统对该线程的任何数据访问都不应该返回旧值,同一个ie线程的写操作被顺序执行
- Causal consistency因果一致性
CAP
组成
- Consistency一致性
- 多个副本之间保持一致性
- 如果一个数据更新后,所有的用户都读取到最新的值,被认为具有强一致性
- 放弃C,达到最终一致性。
- 引入一个时间窗口,多久取决系统设计,只要包括副本之间复制时间
- Availability可用性
- 系统提供的服务一直处于可用状态,并且操作总是能够在有限的时间内返回有效的结果
- 放弃A,系统遇到网络分区或者其它故障,系统一定时间内不可用
- Partition tolerance分区容错性
- 分布式系统在任何网络分区故障时,任然能够保持对外提供一致性和可用性服务,除非整个网络发生故障
- 最基本的是一个分布式系统必然需要面对和解决的问题,架构师根据业务特点在CA之间平衡
- 放弃P,将所有数据放到一个节点,不能保证不出错,但是不会碰到网络分区带来的负面影响,同时放弃系统的可扩展性
XA
概念
名称
- 资源管理器(resource manager)
- 用来管理系统资源,是通向事务资源的途径。数据库就是一种资源管理器。资源管理还应该具有管理事务提交或回滚的能力。
- 事务管理器(transaction manager)
- 事务管理器是分布式事务的核心管理者。事务管理器与每个资源管理器(resource manager)进行通信,协调并完成事务的处理。事务的各个分支由唯一命名进行标识
- Xid 接口
- Xid 接口是 X/Open 事务标识符 XID 结构的 Java 映射。此接口指定三个访问器方法,以检索全局事务格式 ID、全局事务 ID 和分支限定符。Xid 接口供事务管理器和资源管理器使用。此接口对应用程序不可见
说明
- 组织
- 是由X/Open组织提出的分布式事务的规范
- 主要定义了(全局)事务管理器(TM,Transtraction Manager)和(局 部)资源管理器(RM,Resource Manager)之间的接口。
- 主流的关系型 数据库产品都是实现了XA接口的。
- XA接口是双向的系统接口
- 在事务管理器 (TM)以及一个或多个资源管理器(RM)之 间形成通信桥梁。
- 从理论上讲两台机器理论上无法达 到一致的状态,需要引入一个单点进行协调。事务管理器
- 由全局事务管理器管理和协调的事务,可以跨 越多个资源(如数据库或JMS队列)和进程。
- 全局事务管理器一般使用 XA 二阶段提交协议 与数据库进行交互。
过程图
过程
分段提交
说明
-
XA需要两阶段提交: prepare 和 commit.
- 第一阶段为 准备(prepare)阶段。即所有的参与者准备执行事务并锁住需要的资源。参与者ready时,向transaction manager报告已准备就绪。
- 第二阶段为提交阶段(commit)。当transaction manager确认所有参与者都ready后,向所有参与者发送commit命令。
事务协调/管理者
- XA 事务是基于两阶段提交协议的,所以需要有一个事务协调者(transaction manager)来保证所有的事务参与者都完成了准备工作(第一阶段)。
- 如果事务协调者(transaction manager)收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。
- MySQL 在这个XA事务中扮演的是参与者的角色,而不是事务协调者(transaction manager)。
XA性能局限性
- 效率低下,准备阶段的成本持久,全局事务状态的成本持久,性能与本地事务相差10倍左右;
- 提交前,出现故障难以恢复和隔离问题。
TCC方案
应用
- 电商、金融领域落地较多
- 支付宝XTS(蚂蚁金融云的分布式事务服务DTS)
原理
- TCC方案其实是两阶段提交的一种改进
- 其将整个业务逻辑的每个分支显式的分成了Try、Confirm、Cancel三个操作
- Try部分完成业务的准备工作,confirm部分完成业务的提交,cancel部分完成事务的回滚
过程图
过程
- 事务开始时,业务应用会向事务协调器注册启动事务。
- 之后业务应用会调用所有服务的try接口,完成一阶段准备。
- 之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。如果接口调用失败,会进行重试。
缺点
- 对应用的侵入性强。
- 业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
- 实现难度较大。
- 需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。
- 为了满足一致性的要求,confirm和cancel接口必须实现幂等。
总结:
-
上述原因导致TCC方案大多被研发实力较强、有迫切需求的大公司所采用。
-
微服务倡导服务的轻量化、易部署,而TCC方案中很多事务的处理逻辑需要应用自己编码实现,复杂且开发量大
消息事务+最终一致性
解释
- 基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,
- 它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败
- 开源的RocketMQ就支持这一特性
过程图
分析:
- A系统向消息中间件发送一条预备消息
- 消息中间件保存预备消息并返回成功
- A执行本地事务
- A发送提交消息给消息中间件
通过以上4步完成了一个消息事务。对于以上的4个步骤,每个步骤都可能产生错误,下面一一分析:
- 步骤一出错,则整个事务失败,不会执行A的本地操作
- 步骤二出错,则整个事务失败,不会执行A的本地操作
- 步骤三出错,这时候需要回滚预备消息,怎么回滚?
- 答案是A系统实现一个消息中间件的回调接口,消息中间件会去不断执行回调接口,检查A事务执行是否执行成功,如果失败则回滚预备消息
- 步骤四出错,这时候A的本地事务是成功的,那么消息中间件要回滚A吗?
- 答案是不需要,其实通过回调接口,消息中间件能够检查到A执行成功了,这时候其实不需要A发提交消息了,消息中间件可以自己对消息进行提交,从而完成整个消息事务
过程分析
基于消息中间件的两阶段提交往往用在高并发场景下
- 将一个分布式事务拆成一个消息事务(A系统的本地操作+发消息)+B系统的本地操作,
- 其中B系统的操作由消息驱动,只要消息事务成功,那么A操作一定成功,消息也一定发出来了,
- 这时候B会收到消息去执行本地操作,如果本地操作失败,消息会重投,直到B操作成功,这样就变相地实现了A与B的分布式事务
总结
- 虽然上面的方案能够完成A和B的操作,但是A和B并不是严格一致的,而是最终一致的
- 这里牺牲了一致性,换来了性能的大幅度提升。当然,这种玩法也是有风险的,如果B一直执行不成功,那么一致性会被破坏,具体要不要玩,还是得看业务能够承担多少风险。
参考:
《从Paxos到Zookeeper 分布式一致性原理与实践 》[倪超著][电子工业出版社]
XA 分布式事务原理
分布式事务XA