目录
一、什么是分布式事务
分布式事务
就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。
本质上来说,分布式事务就是为了保证不同数据库数据的一致性
和完整性
。
二.分布式事务的产生的原因
2.1 数据库分库分表
随着业务数据规模的快速发展,数据量越来越大,单库单表逐渐成为瓶颈。所以我们对数据库进行了水平拆分,将原单库单表拆分成数据库分片,于是就产生了跨数据库事务
问题。
2.2 应用SOA化
所谓的SOA化,就是业务的服务化。比如原来单机支撑了整个电商网站,现在对整个网站进行拆解,分离出了订单中心、用户中心、库存中心。对于订单中心,有专门的数据库存储订单信息,用户中心也有专门的数据库存储用户信息,库存中心也会有专门的数据库存储库存信息。这时候如果要同时对订单和库存进行操作,那么就会涉及到订单数据库和库存数据库,为了保证数据一致性,就需要用到分布式事务。
2.3 以上的分库分表和多服务都会产生数据一致性的问题
在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成。在分布式网络环境下,我们无法保障所有服务、数据库都百分百可用,一定会出现部分服务、数据库执行成功,另一部分执行失败的问题。当出现部分业务操作成功、部分业务操作失败时,业务数据就会出现不一致。
二、如何进行分布式事务控制
2.1、CAP理论
CAP理论
是分布式事务处理的理论基础:分布式系统在设计时只能在一致性(Consistency)
、可用性(Availability)
、分区容忍性(PartitionTolerance)
中满足两种,无法兼顾三种。
一致性(Consistency)
:多个节点的数据副本需要保持同一时刻数据一致性(强一致性)。可用性(Availability)
:非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。分区容错性(Partition Tolerance)
:将同一服务分布在多个节点中,从而保证某一个节点宕机,仍然有其他节点提供相同的服务。
分布式系统不可避免的出现了多个系统通过网络协同工作的场景,节点之间难免会出现网络中断、网延延迟等现象,这种现象一旦出现就导致数据被分散在不同的节点上,这就是网络分区。
在保证分区容错性的前提下一致性和可用性无法兼顾,如果要提高系统的可用性
就要增加多个节点,如果要保证数据的一致性
就要实现每个节点的数据一致,节点越多可用性越好,但是数据一致性越差。所以,在进行分布式系统设计时,同时满足“一致性”、“可用性”和“分区容忍性”三者是几乎不可能的。
结合电商系统中的一些业务场景来理解CAP
如下图,是商品信息管理的执行流程:
整体执行流程如下
- a.商品服务请求
主数据库
写入商品信息(添加商品、修改商品、删除商品) - b.主数据库向商品服务
响应写入成功
- c.商品服务请求
从数据库读取
商品信息
1、C - Consistency 一致性
一致性
是指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上,从任意结点
读取到的数据都是最新的状态
上图中,商品信息的读写要满足一致性就是要实现如下目标
:
- 商品服务写入主数据库成功,则向从数据库查询新数据也成功
- 商品服务写入主数据库失败,则向从数据库查询新数据也失败
如何实现一致性?
- 写入主数据库后要将数据
同步
到从数据库 - 写入主数据库后,在向从数据库同步期间要将
从数据库锁定
,待同步完成后再释放锁
,以免在新数据写入成功后,向从数据库查询到旧的数据
分布式系统一致性的特点:
- 由于存在数据同步的过程,写操作的响应会有一定的
延迟
- 为了保证数据一致性会对资源暂时锁定,待
数据同步完成释放锁定资源
- 如果请求数据同步失败的结点则会
返回错误信息
,一定不会返回旧数据
2、A - Availability 可用性
可用性
是指任何事务操作都可以得到响应结果
,且不会出现响应超时或响应错误,也就是在集群中一部分节点「故障」
后,集群整体「是否还能响应」
客户端的读写请求。(对数据更新具备高可用性)
简单来说:
一个请求, 必须返回一个响应, 意思是只要收到用户的请求,服务器就必须给出回应
上图中,商品信息读取满足可用性就是要实现如下目标
:
- 从数据库接收到数据查询的请求则
立即能够响应数据查询结果
- 从数据库不允许出现
响应超时
或响应错误
如何实现可用性?
- 写入主数据库后要将数据
同步到从数据库
- 由于要保证从数据库的可用性,
不可将从数据库中的资源进行锁定
- 即时数据还没有同步过来,从数据库也要返回要查询的数据,哪怕是旧数据,如果连旧数据也没有则可以按照约定返回一个默认信息,但
不能返回错误
或响应超时
分布式系统可用性的特点:
- 所有请求都有响应,
且不会出现响应超时或响应错误
,也就是当单个组件无法可用,操作依然可以完成
3、P - Partition tolerance 分区容忍性
通常分布式系统的各各结点部署在
不同的子网
,这就是网络分区
,不可避免的会出现由于网络问题
而导致结点之间通信失败
,此时仍可对外提供服务,这叫分区容忍性
简单来说:
分布式系统集群中, 一个机器坏掉不应该影响其他机器
上图中,商品信息读写满足分区容忍性就是要实现如下目标
:
- 主数据库向从数据库同步数据失败
不影响读写操作
- 其一个结点挂掉不影响另一个结点对外提供服务
如何实现分区容忍性?
- 尽量使用
异步取代同步
操作,例如使用异步方式将数据从主数据库同步到从数据,这样结点之间能有效的实现松耦合
添加从数据库结点
,其中一个从结点挂掉其它从结点提供服务
分布式分区容忍性的特点:
分区容忍性分是布式系统具备的基本能力
2.2、CAP组合方式
上边商品管理的例子是否
同时具备
CAP 呢?
在所有分布式事务场景中不会同时具备 CAP 三个特性
,因为在具备了P的前提下C和A是不能共存的
比如,下图满足了P即表示实现分区容忍:
本图分区容忍的含义是:
- a.主数据库通过网络向从数据库同步数据,可以认为主从数据库部署在不同的分区,通过网络进行交互
- b.当主数据库和从数据库之间的网络出现问题不影响主数据库和从数据库对外提供服务
- c.其中一个节点挂掉不影响另一个节点对外提供服务
如果要实现 C 则必须保证
数据一致性
,在数据同步的时候为防止向从数据库查询不一致的数据则需要将从数据库数据锁定,待同步完成后解锁,如果同步失败从数据库要返回错误信息或超时信息
如果要实现 A 则必须保证数据可用性
,不管任何时候都可以向从数据查询数据,则不会响应超时或返回错误信息。通过分析发现在满足P的前提下 C 和 A 存在矛盾性
所以在生产中对分布式事务处理时要根据需求来确定满足 CAP 的哪两个方面?
2.2.1、AP
放弃一致性,追求分区容忍性和可用性
,这是很多分布式系统设计时的选择。
例如:上边的商品管理,完全可以实现 AP,前提是只要用户可以接受所查询到的数据在一定时间内不是最新的即可。
通常实现 AP 都会保证
最终一致性
,后面将的BASE 理论
就是根据 AP 来扩展的,一些业务场景比如:订单退款,今日退款成功,明日账户到账,只要用户可以接受在一定的时间内到账即可
2.2.2、CP
放弃可用性,追求一致性和分区容错性
,zookeeper 其实就是追求的强一致,又比如跨行转账
,一次转账请求要等待双方银行系统都完成整个事务才算完成
2.2.3、CA
放弃分区容忍性
,即不进行分区,不考虑由于网络不通或结点挂掉的问题,则可以实现一致性和可用性。那么系统将不是一个标准的分布式系统,最常用的关系型数据就满足了 CA
上边的商品管理,如果要实现 CA 则架构如下:
主数据库和从数据库中间不在进行数据同步,数据库可以响应每次的查询请求,通过事务隔离级别实现每个查询请求都可以返回最新的数据
2.2.4、总结
CAP 是一个已经被证实的理论,
一个分布式系统最多只能同时满足:
一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项
。它可以作为进行架构设计、技术选型的考量标准,对于多数大型互联网应用的场景,结点众多、部署分散,而且现在的集群规模越来越大,所以节点故障
、网络故障
是常态,而且要保证服务可用性达到 N 个 9(99.99…%),并要达到良好的响应性能来提高用户体验,因此一般都会做出如下选择:保证 P 和 A
,舍弃 C 强一致
,保证最终一致性
2.3、BASE 理论
2.3.1、强一致性和最终一致性
CAP 理论告诉我们一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三项中的两项,其中AP在实际应用中较多,AP 即舍弃一致性
,保证可用性
和分区容忍性
,但是在实际生产中很多场景都要实现一致性,比如前边我们举的例子主数据库向从数据库同步数据,即使不要一致性,但是最终也要将数据同步成功来保证数据一致,这种一致性和 CAP 中的一致性不同,CAP 中的一致性要求
在任何时间查询每个结点数据都必须一致,它强调的是强一致性
,但是最终一致性是允许可以在一段时间内每个结点的数据不一致,但是经过一段时间每个结点的数据必须一致,它强调的是最终数据的一致性
2.3.2、Base 理论介绍
BASE
是 Basically Available(基本可用)
、Soft state(软状态)
和 Eventually consistent (最终一致性)
三个短语的缩写。BASE 理论是对 CAP 中 AP 的一个扩展
,通过牺牲强一致性
来获得可用性,当出现故障允许部分不可用但要保证核心功能可用
,允许数据在一段时间内是不一致的,但最终达到一致状态。满足BASE理论的事务,我们称之为“柔性事务
”
基本可用
:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。如电商网站交易付款出现问题了,商品依然可以正常浏览软状态
:由于不要求强一致性,所以BASE允许系统中存在中间状态(也叫软状态),这个状态不影响系统可用性,如订单的"支付中"、“数据同步中”等状态,待数据最终一致后状态改为“成功”状态最终一致
:最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的"支付中"状态,最终会变 为“支付成功”或者"支付失败",使订单状态与实际交易结果达成一致,但需要一定时间的延迟、等待
三、分布式事务的几种解决方案
分布式场景业界常见的解决方案有 2PC、3PC、TCC、可靠消息最终一致性、最大努力通知这几种。
3.1、2PC(两阶段提交)
3.1.1、简介
2PC(Two-phase commit protocol),中文叫两阶段提交,
两阶段提交是一种强一致性设计
,2PC 引入一个事务协调者((Coordinator))的角色
来协调管理
各参与者(也可称之为各本地资源)的行为(提交和回滚
),并最终决定这些参与者是否要真正执行事务.
两阶段是将整个事务流程分为两个阶段:分别指的是准备阶段(Prepare phase)
和提交阶段(commitphase)
两个阶段, 2是指两个阶段, P是指准备阶段, C是指提交阶段。
注意
:这只是协议或者说是理论指导,只阐述了大方向,具体落地还是有会有差异的
3.1.2、举个栗子说明
张三和李四好久不见,老友约起聚餐,饭店老板要求先买单,才能出票,这时张三和李四分别抱怨近况不如意,囊中羞涩,都不愿意请客,这时只能AA。只有张三和李四都付款,老板才能出票安排就餐。但由于张三和李四都是铁公鸡,形成了尴尬的一幕:
准备阶段
:老板要求张三付款,张三付款,老板要求李四付款,李四付款。
提交阶段
:老板出票,两人拿票纷纷落座就餐。
例子中形成了一个事务
,若张三或李四其中一人拒绝付款,或钱不够,店老板都不会给出票,并且会把已收款退回。
整个事务过程
由事务管理器
和参与者
组成,店老板
就是事务管理器
,张三
、李四
就是事务参与者
,事务管理器负责决策
整个分布式事务的提交
和回滚
,事务参与者负责自己本地事务
的提交
和回滚
在计算机中部分关系数据库如Oracle
、MySQL支持两阶段提交协议
,如下:
- 1、
准备阶段(Prepare phase)
:事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务
,并写本地的Undo/Redo日志
,此时事务没有提交
。(Undo日志是记录修改前的数据,用于数据库回滚,Redo日志是记录修改后的数据,用于提交事务后写入数据文件) - 2、
提交阶段(commit phase)
:如果事务管理器收到了参与者的执行失败
或者超时消息
时,直接给每个参与者发送回滚(Rollback)消息
;否则,发送提交(Commit)消息
;参与者根据事务管理器的指令执行提交或者回滚操作,并释放
事务处理过程中使用的锁资源。
注意:必须在最后阶段释放锁资源