赞
踩
目录
- 分析分布式事务产生的原因:跨服务、跨数据源的业务
- 思考解决分布式事务的基本思路
- 了解Seata框架,学习Seata原理
- 利用Seata解决分布式事务问题
本地事务(Local Transaction),也就是传统的单机事务,或翻译成"局部事务"更好,才好与稍后的"全局事务"相对应,本地事务是指仅操作单一事务资源的、不需要全局事务管理器进行协调的事务。
与本地事务相对的是全局事务(Global Transaction),有一些资料中也将其称为外部事务(External Transaction)。
但是现在我们要研究的是微服务,而微服务的业务往往比较复杂,可能一个业务就会跨越多个服务,而每个服务又会有自己独立的数据库,也就是独立的事务,这个时候你再靠数据库本身的特性,就很难保证整个业务的ACID了。
分布式事务(Distributed Transaction)
分布式事务,就是指不是在单个服务或单个数据库架构下产生的事务。
- 每个微服务的本地事务,也可以称为分支事务,每一个分支事务就是传统的单体事务,多个有关联的分支事务一起就组成了全局事务,但全局事务跨多个服务、跨多个数据库,因此全局事务,即分布式事务并未遵循ACID的原则,归其原因就是参与事务的多个子业务在不同的微服务中,跨越了不同的数据库,虽然每个单独的业务都能在本地遵循ACID,但是它们互相之间没有感知(各个分分支事务之间互相是感知不到的),不知道有人失败了,无法保证最终结果的统一,也就无法遵循ACID的事务特性了,所以,我们必须保证整个全局事务同时成功或失败。
1. 跨数据源或跨数据库实例的分布式事务
比如有以下两个场景:
- 单体系统下,同一个系统使用了多个数据库源连接不同的数据库
- 分布式、微服务系统,各系统服务使用不同的数据库
2. 跨服务,即跨JVM进程的分布式事务
- 分布式、微服务系统,各系统服务使用不同的数据库或者是同一个数据库,都会产生分布式事务,因为它们使用的是不同的数据库连接和事务管理器
例如电商行业中比较常见的下单付款业务的整体流程,包括下面几个行为:
完成上面的操作需要访问四个不同的微服务和四个不同的数据库,订单的创建(创建订单并写入数据库)、购物车的清空、账户的扣款(用户账户余额的扣减)、商品库存的扣减在每一个服务和数据库内是一个本地事务,可以保证ACID原则,但我们最终希望的肯定是我这个下单业务一旦执行,每一个都要成功,但是当我们把这几件事情看做一个"业务",要满足"业务"的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象,这就是分布式系统下的事务了,但此时ACID难以满足,这就是分布式事务要解决的问题。
- 在分布式系统下,一个业务跨越多个服务或数据源合作完成,而且每一个服务都有事务,每个服务的事务都是一个分支事务,要保证所有分支事务最终状态一致,也就是这多个事务必须同时成功或失败,这样的事务就是分布式事务,其中的每个服务的事务就是一个分支事务,整个业务称为全局事务。
1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标:
Consistency(一致性):同一个数据在同一时刻是相同的 => 强一致性
Availability(可用性)
Partition tolerance (分区容错性)
它们的第一个字母分别是C、A、P,Eric Brewer认为任何分布式系统架构方案都不可能同时满足这3个目标,这个结论就叫做 CAP 定理,CAP定理又称CAP原则。
Consistency(一致性):用户在访问分布式系统中的任意节点时,得到的数据必须是一致的。
Availability (可用性):用户在访问集群中的任意健康节点或非故障节点时,必须能得到响应,而不是超时或拒绝或阻塞。
Partition(分区):就是当分布式系统节点之间因为出现网络故障或其它原因导致分布式系统中的部分节点之间无法通信的情况,导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。
如上图,node01和node02之间网关畅通,但是与node03之间网络断开,于是node03成为一个独立的网络分区;node01和node02在一个网络分区。
Tolerance(容错):在集群出现分区时,整个系统仍能持续对外正常提供服务。
当出现网络分区时,如图:
由于网络故障,当我们把数据写入node01时,可以与node02完成数据同步,但是无法同步给node03。现在有两种选择:
允许用户任意读写,保证可用性,那就不能等待网络恢复,但由于node03无法完成数据同步,就会出现数据不一致的情况,满足AP。
不允许用户任意读写,用户请求到node03节点时直接阻塞该用户请求,直到网络恢复,分区消失,完成数据同步后,该节点才对外提供服务,此时再唤醒被阻塞的用户线程,再让用户正常去访问,这样就确保了数据的一致性,但牺牲了可用性,因此node03节点是一个健康的节点,而你用户打进来却被该节点阻塞了,此时不就是牺牲了可用性,满足CP。
- 舍弃P在分布式系统中几乎是不存在的,首先在分布式环境下,网络分区是一个自然的事实,因为分区是必然的,所以如果舍弃P,意味着就要舍弃分布式系统,那也就没有必要再讨论CAP理论了,所以,对于一个分布式系统来说,P是一个基本要求,CAP三者中,只能再CA两者之间做权衡,并且要想进办法提升P。
- 要想提升系统的分区容错性,需要通过提升基础设施的稳定性来保证。
既然分布式系统要遵循CAP定理,那么问题来了,我到底是牺牲一致性还是可用性呢?如果牺牲了可用性,出现数据不一致该怎么处理?
因此就出现了BASE理论,BASE理论是对CAP的一种解决思路,包含三个思想:
- Basically Available(基本可用):分布式系统出现故障时,允许损失部分可用性,即或来保证核心可用。
- Soft State(软状态):在一定时间内,允许系统出现中间状态,比如临时的不一致状态,而该中间状态不会影响系统的整体可用性 => 最终达到数据的一致性(最终一致性)。
- Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据的一致性。
简单来说,BASE理论就是一种取舍的方案,不再追求完美,而是最终达成目标,BASE理论为CAP理论的延申,主要是解决CAP理论中分布式系统的可用性和一致性不可兼得的问题,BASE理论是对CAP中一致性和可用性的一个权衡,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但每个应用都可以根据自身的业务特点,采用适当的方式来使得系统达到最终一致性。
可以说BASE理论是CAP中一致性的妥协,和传统事务的ACID截然不同,BASE理论不追求强一致性,而是允许数据在一段时间内是不一致的,但最终达到一致状态,从而获得更高的可用性和性能。
- BASE和ACID是相反的,它完全不同于ACID的强一致性模型,ACID是传统数据库常用的设计理念,追求强一致性模式,而BASE支持的是大型分布式系统,提出牺牲强一致性获得高可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。
- ACID和BASE代表了两种截然相反的设计哲学,在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此ACID和BASE又会结合使用。
分布式事务最大的问题就是各个子事务的一致性问题,可以借鉴CAP定理和BASE理论,因此解决分布式事务有两种解决思路或有两个方向:
但不管是哪一种模式,都需要在子系统事务之间互相通讯、协调事务状态,也就是需要一个事务协调者(TC),来帮助分布式事务中的各个子事务进行一个通信或感知对方彼此的状态:
这里的子系统事务,称为分支事务,有关联的各个分支事务在一起称为全局事务。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。