分布式事务CAP两阶段提交及三阶段提交详解

目录
  • 1 关于分布式系统
    • 1.1 介绍
    • 1.2 优势和不足
  • 2 分布式事务
    • 2.1 CAP理论
    • 2.2 CAP的组合情况
    • 2.3 数据一致性模型
    • 2.4 分布式事务应用场景
      • 2.4.1 典型支付场景
      • 2.4.2 在线下单
      • 2.4.3 跨行转账
    • 2.5 常见分布式一致性保障(分布式事务解决方案)
      • 2.5.1 XA 两阶段提交协议
      • 2.5.2 XA三阶段提交
      • 2.5.3 MQ事务
      • 2.5.4 TCC事务
      • 2.5.5 最终补偿机制,同于MQ事务

1 关于分布式系统

1.1 介绍

我们常见的单体结构的集中式系统,一般整个项目就是一个独立的应用,所有的模块都聚合在一起。明显的弊端就是不易扩展、发布冗重、服务治理不好做。

所以我们把整个系统拆分成若干个具备独立运行能力的计算服务的集合,而从用户的角度看,是一个完整的系统,但实际上,它是一个分布式服务的集合。

分布式系统主要从以下几个方面进行裂变:

  • 应用可以从业务领域拆分成多个module,每个module还可以再按项目结构分成接口层、业务层、数据访问层;当然也可以按访问入口进行拆分,如移动、桌面、Web端访问的是不同的类型接口服务;
  • 数据库可以按业务类型拆分成多个实例,还可以对单库或单表进行分库分表;参考我的这篇《Mysql数据库分库分表全面瓦解》
  • 增加一些中间件,来保证分布式系统的高可用,如分布式缓存、搜索服务、文件服务、消息队列、非关系型数据库等中间件;

1.2 优势和不足

分布式系统可以解决集中式不便扩展的弊端,提供了便捷的扩展性、独立的服务治理,并提高了安全可靠性。随着微服务技术(Spring Cloud、Dubbo) 以及容器技术(Kubernetes、Docker)的大热,分布式技术发展非常迅速。

不足的地方:分布式系统虽好,也带来了系统的复杂性,如分布式事务、分布式锁、分布式session、数据一致性等都是现在分布式系统中需要解决的难题,虽然已经有很多成熟的方案,但都不完美。

分布式系统的便利,其实是牺牲了一些开发、测试、运维 成本的,让工作量增加了,所以分布式系统管理不好反而会变成一种负担。

2 分布式事务

分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

分布式场景下一次完整的操作由不同的action组成,这些actions可能分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些action要么全部成功,要么全部失败。保证单个完整操作的原子性。

本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

2.1 CAP理论

CAP 定理(也称为 Brewer 定理),指的是在分布式计算环境下,有3个核心的需求:

1、一致性(Consistency):再分布,所有实例节点同一时间看到是相同的数据

2、可用性(Availability):不管是否成功,确保每一个请求都能接收到响应

3、分区容错性(Partition Tolerance):系统任意分区后,在网络故障时,仍能操作

CAP理论告诉我们,分布式系统不可能同时满足以下三种。最多只能同时满足其中的两项,因为很多时候P是必须的, 因此往往选择就在CP或者AP中

2.2 CAP的组合情况

CA: 放弃分区容错性。非分布式架构,比如关系数据库,因为没有分区,但是在分布式系统下,CA组合就不建议了。

AP: 放弃强一致性。追求最终一致性,类似的场景比如转账,可以接受两小时后到账,Eureka的注册也是类似的做法。

CP: 放弃可用性。zookeeper在leader宕机后,选举期间是不提供服务的。类似的场景比如支付完成之后出订单,必须一进一出都完成才行。

结论:在分布式系统中AP运用的最多,因为他放弃的是强一致性,追求的是最终一致性,性价比最高

2.3 数据一致性模型

分布式系统通过同步数据的副本来提高系统的可靠性和容错性,而且数据的不同的副本,合理会存在不同的机器或集群上。

强一致性:当用户的操作完成之后,会立马被同步到不同的数据副本中,后续其他任意请求都会获得更新过的值。这种对用户的可见性是最友好的,能始终保证读到正确的值。根据 CAP 理论,这种实现需要牺牲可用性。

弱一致性:系统并不保证所有请求的访问都会获得最新值。数据写入成功之后,不承诺立即可以读,也不承诺具体多久之后可以读到,甚至读不到。在请求获得数据更新的这段时间,我i们称之为“不一致性窗口”。

最终一致性:是弱一致性的一种。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。

常见的事务处理机制:

1、Master-Slave 复制:写请求由 Master 负责,写入 Master 后,由 Master 同步到 Slave 上。

异步同步,所以是弱/最终一致性。

2、Master-Master 主主复制

异步同步,最终的一致性,多个节点间需要序列化协议。

2.4 分布式事务应用场景

2.4.1 典型支付场景

这是最经典的场景。支付过程,要先对买家账户进行扣款,同时对卖家账户进行付款,

像这类的操作,必须在一个事务中执行,保证原子性,要么都成功,要么都不成功。但是往往买家的支付平台和卖家的支付平台不一致,即使都在一个平台下,所属的业务服务和数据服务

(归属不同表甚至不同库,比如卖家中心库、卖家中心库)也不是同一个。针对于不同的业务平台、不同的数据库做操作必然要引入分布式事务。

2.4.2 在线下单

同理,买家在电商平台下单,往往会涉及到两个动作,一个是扣库存,第二个是更新订单状态,库存和订单一般属于不同的数据库,需要使用分布式事务保证数据一致性。

2.4.3 跨行转账

跨行转账问题也是一个典型的分布式事务,用户A同学向B同学的账户转账500,要先进行A同学的账户-500,然后B同学的账户+500,既然是不同的银行,

涉及不同的业务平台,为了保证这两个操作步骤的一致,分布式事务必然要被引入。

2.5 常见分布式一致性保障(分布式事务解决方案)

2.5.1 XA 两阶段提交协议

两阶段提交协议(Two-phase commit protocol),简称2PC,过程涉及到协调者和参与者。

它是一种强一致性设计,引入一个事务协调者的角色来协调管理各参与者的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。

第一阶段(准备阶段)

为事务协调者的节点会首先向所有的参与者节点发送Prepare请求。

在接到Prepare请求之后,每一个参与者节点会各自执行与事务有关的数据更新,写入Undo Log(撤销)和 Redo Log(重做)。

如果参与者执行成功,暂时不提交事务,而是向事务协调节点返回“完成”消息。当事务协调者接到了所有参与者的返回消息,整个分布式事务将会进入第二阶段。

假如在第一阶段有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的请求,即分布式事务执行失败。如下图:

第二阶段(提交阶段)

如果事务协调节点在之前所收到都是正向返回,那么它将会向所有事务参与者发出Commit请求。

接到Commit请求之后,事务参与者节点会各自进行本地的事务提交,并释放锁资源。当本地事务完成提交后,将会向事务协调者返回“完成”消息。

当事务协调者接收到所有事务参与者的“完成”反馈,整个分布式事务完成。

当有一个Commit 不成功,那其他的应该也是提交不成功的。

2.5.2 XA三阶段提交

三阶段提交:CanCommit 阶段、PreCommit 阶段、DoCommit 阶段,简称3PC

三阶段提交协议(Three-phase commit protocol,3PC),是二阶段提交(2PC)的改进版本。与两阶段提交不同的是,三阶段提交有两个改动点:

引入超时机制。同时在协调者和参与者中都引入超时机制。

在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。

即 3PC 把 2PC 的准备阶段再次一分为二,这样三阶段提交就有 CanCommit、PreCommit、DoCommit 三个阶段。当 CanCommit、PreCommit、DoCommit

的任意一个步骤失败或者等待超时,执行RollBack。

2.5.3 MQ事务

利用消息中间件来异步完成事务的后半部分更新,实现系统的最终一致性。这个方式避免了像XA协议那样的性能问题。

下面的图中,使用MQ完成事务在分布式的另外一个子系统上的操作,保证了动作一致性。

2.5.4 TCC事务

TCC事务是Try、Confirm、Cancel三种指令的缩写,其逻辑模式类似于XA两阶段提交,但是实现方式是在代码层面人为实现。2PC 和 3PC 都是数据库层面的,而 TCC 是业务层面的分布式事务。

分布式事务除了上面提到的数据库层面的操作外,还包括发送短信、邮件这种业务操作等,这时候 TCC 就有用武之地了!

图中就是一个典型的分布式系统的原子性操作,涉及A、B、C三个服务的执行。如果有一个服务 try 出问题,整个事务管理器就执行calcel,如果三个try都成功,才执行confirm做正式提交。

2.5.5 最终补偿机制,同于MQ事务

最后使用补偿机制做最后的一致性保障,MQ方案尽量使用补偿机制进行保障。

以上就是分布式事务CAP两阶段提交及三阶段提交详解的详细内容,更多关于分布式事务CAP及两阶三阶段提交的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅谈Java实现分布式事务的三种方案

    一.问题描述 用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库.由库存服务去维护库存数据库的信息.下图是系统结构图: 如何实现两个分布式服务(订单服务.库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个分布式服务的事务的一致性. 尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下: 订单支付结果通知方法{ ​ 更新支付表中支付状态为"成功". ​ 远程调用减库存接口减库存. } 上边的逻辑说明: 1.更新支付表状态为本

  • 详解Java分布式事务的 6 种解决方案

    介绍 在分布式系统.微服务架构大行其道的今天,服务间互相调用出现失败已经成为常态.如何处理异常,如何保证数据一致性,成为微服务设计过程中,绕不开的一个难题. 在不同的业务场景下,解决方案会有所差异,常见的方式有: 阻塞式重试: 2PC.3PC 传统事务: 使用队列,后台异步处理: TCC 补偿事务: 本地消息表(异步确保): MQ 事务. 本文侧重于其他几项,关于 2PC.3PC 传统事务,网上资料已经非常多了,这里不多做重复. 阻塞式重试 在微服务架构中,阻塞式重试是比较常见的一种方式.伪代码

  • 详解Java TCC分布式事务实现原理

    概述 之前网上看到很多写分布式事务的文章,不过大多都是将分布式事务各种技术方案简单介绍一下.很多朋友看了还是不知道分布式事务到底怎么回事,在项目里到底如何使用. 所以这篇文章,就用大白话+手工绘图,并结合一个电商系统的案例实践,来给大家讲清楚到底什么是 TCC 分布式事务. 业务场景介绍 咱们先来看看业务场景,假设你现在有一个电商系统,里面有一个支付订单的场景. 那对一个订单支付之后,我们需要做下面的步骤: 更改订单的状态为"已支付" 扣减商品库存 给会员增加积分 创建销售出库单通知仓

  • 图文精讲java常见分布式事务理论与解决方案

    目录 CAP理论 C(Consistence):一致性 A(Availability):可用性 P(Partition tolerance):分区容错性 BASE理论 BA(Basically Available):基本可用 S(Soft-state):软状态 E(Eventually Consistent):最终一致性 一致性hash Gossip协议 Gossip协议的特点: Raft算法 选举 复制 分布式事务 2PC 3PC TCC 如何解决某个节点故障的问题?如何解决数据一致性的问题?

  • 分布式事务CAP两阶段提交及三阶段提交详解

    目录 1 关于分布式系统 1.1 介绍 1.2 优势和不足 2 分布式事务 2.1 CAP理论 2.2 CAP的组合情况 2.3 数据一致性模型 2.4 分布式事务应用场景 2.4.1 典型支付场景 2.4.2 在线下单 2.4.3 跨行转账 2.5 常见分布式一致性保障(分布式事务解决方案) 2.5.1 XA 两阶段提交协议 2.5.2 XA三阶段提交 2.5.3 MQ事务 2.5.4 TCC事务 2.5.5 最终补偿机制,同于MQ事务 1 关于分布式系统 1.1 介绍 我们常见的单体结构的集

  • Java比较两个对象大小的三种方法详解

    目录 一. 为什么需要比较对象 二. 元素的比较 1. 基本类型的比较 2. 引用类型的比较 三. 对象比较的方法 1. equals方法比较 2. 基于Comparable接口的比较 3. 基于Comparator接口的比较 4. 三种比较方式对比 一. 为什么需要比较对象 上一节介绍了优先级队列,在优先级队列中插入的元素必须能比较大小,如果不能比较大小,如插入两个学生类型的元素,会报ClassCastException异常 示例: class Student{ String name; in

  • Mysql数据库事务的脏读幻读及不可重复读详解

    目录 一.什么是数据库事务 二.事务的ACID原则 1. 原子性(Atomicity) 2. 一致性(Consistency) 3. 持久性(Durability) 4. 隔离性(Isolation) 三.隔离带来的问题 1. 脏读 2. 不可重复读 3.幻读 四.手动测试下事务的过程 一.什么是数据库事务 数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位.事务由事务开始与事务结束之间执行的全部数

  • Python图片存储和访问的三种方式详解

    目录 前言 数据准备 一个可以玩的数据集 图像存储的设置 LMDB HDF5 单一图像的存储 存储到 磁盘 存储到 LMDB 存储 HDF5 存储方式对比 多个图像的存储 多图像调整代码 准备数据集对比 单一图像的读取 从 磁盘 读取 从 LMDB 读取 从 HDF5 读取 读取方式对比 多个图像的读取 多图像调整代码 准备数据集对比 读写操作综合比较 数据对比 并行操作 前言 ImageNet 是一个著名的公共图像数据库,用于训练对象分类.检测和分割等任务的模型,它包含超过 1400 万张图像

  • 微信小程序中form 表单提交和取值实例详解

    微信小程序中form 表单提交和取值实例详解 我们知道,如果我们直接给 input 添加 bindinput,比如:<input bindinput="onUsernameInput" />,那么可以在 onUsernameInput 中直接使用 e.detail.value,即: onUsernameInput : function(e) { e.detail.value; } 但是,如果有多个输入控件,我们不可能为每个控件添加 bindinput.bindchange

  • Android 三种动画详解及简单实例

    Android 三种动画详解 帧动画 一张张图片不断的切换,形成动画效果 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="

  • Service Activity的三种交互方式(详解)

    service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remote Sercie):用于android系统内部的应用程序之间 前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好. 后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可. 编写不需和Activity交互的本地服务示例 本地服务编写比较简单.首先,要创建一个Se

  • Python之两种模式的生产者消费者模型详解

    第一种使用queue队列实现: #生产者消费者模型 其实服务器集群就是这个模型 # 这里介绍的是非yield方法实现过程 import threading,time import queue q = queue.Queue(maxsize=10) def Producer(anme): # for i in range(10): # q.put('骨头%s'%i) count = 1 while True: q.put('骨头%s'%count) print('生产了骨头',count) cou

  • python解析命令行参数的三种方法详解

    这篇文章主要介绍了python解析命令行参数的三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python解析命令行参数主要有三种方法:sys.argv.argparse解析.getopt解析 方法一:sys.argv -- 命令行执行:python test_命令行传参.py 1,2,3 1000 # test_命令行传参.py import sys def para_input(): print(len(sys.argv)) #

  • Java每隔两个数删掉一个数问题详解

    题目描述 有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置. 以8个数(N=7)为例:{0,1,2,3,4,5,6,7}, 0->1->2(删除)->3->4->5(删除)->6->7->0(删除) 如此循环直到最后一个数被删除. 输入: 8 输出: 6 以下是本篇文章正文内容,下面案例可供参考 解题思路 一看到这个题目,就想到了队列的约瑟夫环的问题 此题思路:将两个数字取出来放到

随机推荐