引言
本文目录结构:
1. 分布式事务产生的背景
在微服务环境下,因为会根据不同的业务会拆分成不同的服务,比如会员服务、订单服务、商品服务等。让专业的人做专业的事情,每个服务都有自己独立的数据库,并且是独立运行,互不影响。
服务与服务之间通讯采用RPC远程调用技术,但是每个服务中都有自己独立的数据源,即自己独立的本地事务。两个服务相互通讯的时候,两个本地事务互不影响,两者之间没有耦合,但是要保证事务的特性,如“一致性”,从而出现分布式事务产生问题的产生。
举例 「订单服务和库存服务」:在电商系统中,下单和扣库存如何保持一致?
- 用户先下单后,扣库存失败,那么将会导致超卖;
- 如果下单不成功,扣库存成功,那么会导致少卖。
- 这两种情况都会导致运营成本增加,在严重情况下需要赔付。
所以需要有解决方案去解决上面两个服务“一致性”的问题,这就涉及到了分布式事务了。
2. 解决分布式事务基本理论
2.1 ACID酸碱平衡理论
如何保证强一致性呢?在学习关系型数据库的时候都学习了ACID原理,关系型数据库天生就是解决具有复杂事务场景的问题,关系型数据库完全满足ACID的特性。这里对ACID做个简单的介绍。
数据库管理系统中事务(transaction)的四个特性(分析时根据首字母缩写依次解释):
- 「原子性」(Atomicity):指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 「一致性」(Consistency):事务前后数据的完整性必须保持一致。
- 「隔离性」(Isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 「持久性」(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位(执行单个逻辑功能的一组指令或操作称为事务)。
2.2 CAP(帽子原理)
由于对系统或者数据进行了拆分,我们的系统不再是单机系统,而是分布式系统,针对分布式系统的CAP原理包含如下三个元素。
- 「C:Consistency」一致性:在分布式系统中的所有数据备份,在同一时刻具有同样的值,所有节点在同一时刻读取的数据都是最新的数据副本。
- 「A:Availability」可用性:好的响应性能。完全的可用性指的是在任何故障模型下,服务都会在有限的时间内处理完成并进行响应。
- 「P: Partition tolerance」分区容忍性:尽管网络上有部分消息丢失,但系统仍然可继续工作。
CAP原理证明,任何分布式系统只可同时满足以上两点,无法三者兼顾。。因此在进行分布式架构设计时,必须做出取舍。
- 如果在网络上有消息丢失,也就是出现了网络分区,则复制操作可能会被延后,如果这时我们的使用方等待复制完成再返回,则可能导致在有限时间内无法返回,就失去了可用性。
- 而如果使用方不等待复制完成,而在主分片写完后直接返回,则具有了可用性,但是失去了一致性。
而对于分布式数据系统,分区容忍性是基本要求,否则就失去了价值。因此设计分布式数据系统,就是在一致性和可用性之间取一个平衡。
「对于大多数web应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向」。当然,牺牲一致性,并不是完全不管数据的一致性,否则数据是混乱的,那么系统可用性再高分布式再好也没有了价值。牺牲一致性,只是不再要求关系型数据库中的强一致性,而是只要系统能达到最终一致性即可。
考虑到客户体验,这个最终一致的时间窗口,要尽可能的对用户透明,也就是需要保障「用户感知到的一致性」。通常是通过数据的多份异步复制来实现系统的高可用和数据的最终一致性的,用户感知到的一致性”的时间窗口则取决于数据复制到一致状态的时间。
2.3 Base(碱)
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的简写,由 eBay 架构师 Dan Pritchett 于 2008 年在《BASE: An Acid Alternative》(论文地址点 这里)论文中首次提出。
BASE 思想与 ACID 原理截然不同,它满足 CAP 原理,通过牺牲强一致性获得可用性, 一般应用于服务化系统的应用层或者大数据处理系统中,通过达到最终一致性来尽量满足业务的绝大多数需求。
BASE 模型包含如下三个元素:
- 「BA:Basically Available (基本可用)」 :指分布式系统在出现故障的时候,允许损失部分可用性,保证核心可用。但不等价于不可用。(比如:搜索引擎0.5秒返回查询结果,但由于故障,2秒响应查询结果;网页访问过大时,部分用户提供降级服务等。)
- 「S: Soft State(软状态)」 :指允许系统存在中间状态,并且该中间状态不会影响系统整体可用性,即允许系统在不同节点间副本同步的时候存在时延。
- 「E:Eventually Consistent (最终一致) 」 :系统中的所有数据副本经过一定时间后,最终能够达到一致的状态,不需要实时保证系统数据的强一致性,最终一致性是弱一致性的一种特殊情况。
2.4 柔性事务和刚性事务
「柔性事务」 满足BASE理论(基本可用,最终一致)
「刚性事务」 满足ACID理论
「柔性事务」 分为:
- 两阶段型
- 补偿型
- 异步确保型
- 最大努力通知型
支付宝整个架构是SOA架构,因此传统单机环境下数据库的ACID事务满足了分布式环境下的业务需要,以上几种事务类似就是针对分布式环境下业务需要设定的。
3. 分布式事务常见解决方案
想要彻底解决分布式事务,主要有以下方案:
- 「传统模式使用Jta+Atomikos」
- 「2PC与3PC」
- 「回调通知补偿型」
- 「阿里巴巴TCC补偿框架」
- 「可靠消息模式」
- 「LCN框架」
- 「阿里GTS框架」
3.1 分布式一致性协议
3.1.1 XA接口
XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。
XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁。
XA之所以需要引入事务管理器是因为在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一个单点进行协调。事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库或JMS队列)。
3.1.2 JTA规范
作为JAVA平台上事务规范JTA(Java Transaction API)也定义了对XA事务的支持,实际上,JTA是基于XA架构上建模的。
在JTA 中,事务管理器抽象为javax.transaction.TransactionManager
接口,并通过底层事务服务(即JTS)实现。像很多其他的java规范一样,JTA仅仅定义了接口,具体的实现则是由供应商(如J2EE厂商)负责提供,目前JTA的实现主要由以下几种:
- J2EE容器所提供的 「JTA实现(JBoss)」。
- 「独立的JTA实现」:如JOTM,Atomikos。这些实现可以应用在那些不使用J2EE应用服务器的环境里用以提供分布式事务保证。如Tomcat,Jetty以及普通的java应用。
3.2 两段提交协议(2PC)
交易中间件与数据库通过 XA 接口规范,使用两阶段提交来完成一个全局事务, XA 规范的基础是两阶段提交协议。
- 第一阶段是 「表决阶段」 ,所有参与者都将本事务能否成功的信息反馈发给协调者;
- 第二阶段是 「执行阶段」 ,协调者根据所有参与者的反馈,通知所有参与者,步调一致地在所有分支上提交或者回滚。
两阶段提交方案应用非常广泛,几乎所有商业OLTP数据库都支持XA协议。但是两阶段提交方案锁定资源时间长,对性能影响很大,基本不适合解决微服务事务问题。
缺点:如果协调者宕机,参与者没有协调者指挥,则会一直阻塞。
3.3 三段提交协议(3PC)
三阶段提交协议是两阶段提交协议的改进版本。它通过超时机制解决了阻塞的问题,并且把两个阶段增加为三个阶段:
- 「询问阶段」:协调者询问参与者是否可以完成指令,参与者只需要回答是还是不是,而不需要做真正的操作,这个阶段超时导致中止。
- 「准备阶段」:如果在询问阶段所有的参与者都返回可以执行操作,协调者向参与者发送预执行请求,然后参与者写redo和undo日志,执行操作,但是不提交操作;如果在询问阶段任何参与者返回不能执行操作的结果,则协调者向参与者发送中止请求,这里的逻辑与两阶段提交协议的的准备阶段是相似的,这个阶段超时导致成功。
- 「提交阶段」:如果每个参与者在准备阶段返回准备成功,也就是预留资源和执行操作成功,协调者向参与者发起提交指令,参与者提交资源变更的事务,释放锁定的资源;如果任何一个参与者返回准备失败,也就是预留资源或者执行操作失败,协调者向参与者发起中止指令,参与者取消已经变更的事务,执行undo日志,释放锁定的资源,这里的逻辑与两阶段提交协议的提交阶段一致。
2PC与3PC提交区别:
- 增加了一个「询问阶段」,询问阶段可以确保尽可能早的发现无法执行操作而需要中止的行为,但是它并不能发现所有的这种行为,只会减少这种情况的发生。在准备阶段以后,协调者和参与者执行的任务中都增加了超时,一旦超时,协调者和参与者都继续提交事务,默认为成功,这也是根据概率统计上超时后默认成功的正确性最大。
- 三阶段提交协议与两阶段提交协议相比,具有如上的优点,但是一旦发生超时,系统仍然会发生不一致,只不过这种情况很少见罢了,好处就是至少不会阻塞和永远锁定资源。
3.4 其它
参考文献:
- TCC参考文章:《终于有人把“TCC分布式事务”实现原理讲明白了!》
- 异步回调模式:《分布式一致性保证模式之【异步确保模式 】》
- 最终一致性模式:《分布式事务——消息最终一致性方案》
- 可靠消息模式:《分布式事务解决方案之可靠消息最终一致性》
4. 总结