在微服务架构中的数据一致性

当从传统的单体应用架构转移到微服务架构时,特别是涉及数据一致性时,数据一致性是微服务架构中最困难的部分。传统的单体应用中,一个共享的关系型数据库负责处理数据一致性。在微服务架构中,如果使用“每个服务一个数据库”的模式,那么每个微服务都有自己的数据存储。因此,数据库在应用程序之间是分布式的。如果每个应用程序使用不同的技术来管理它们的数据,比如非关系型数据库,这种分布式架构虽然在数据管理方面有许多好处,比如可伸缩性、高可用性、灵活性等,但在数据管理方面也存在一些关键问题,比如事务管理、数据一致性/完整性等方面。

bb782f34558716146e9febef4e6adde2.png
1*hJ-Mu2gk7w5h8D7qu90Rvw.png

问题:分布式系统中的数据一致性

对于单体应用程序,通过ACID事务,一个共享的关系型数据库处理并保证数据的一致性。ACID 是一个缩写,具体含义如下:

A 原子性:事务的所有步骤要么全部成功,要么全部失败,没有部分状态,全有或全无。•C 一致性:事务结束时数据库中的所有数据都是一致的。•I 隔离性:同一时间只有一个事务可以访问数据,其他事务必须等待当前事务完成。•D 持久性:数据在事务结束时被持久化到数据库中。

为了保持强数据一致性,关系型数据库管理系统支持ACID特性。

70205cc696036322df964c5352bcb138.png

1*AKnWPWPT56Cb7JSSdpLFaA.png

但在微服务架构中,每个微服务都有自己的数据存储,并采用不同的技术。因此,没有中央数据库,也没有单一的工作单元。业务逻辑被跨越到多个本地事务中。这意味着你不能在微服务架构中的数据库之间使用单一的事务工作单元。但你仍然需要在你的应用程序中使用ACID特性。

06c470c0cc6f68e8c000c1f9d1b05ce0.png

1*ZAFdGYOaZQj62XyOfEjiFw.png

让我们用一个简单的样例场景来解释。在一个订单管理系统中,可能存在库存管理、支付和订单管理等服务。假设这些服务都按照微服务架构设计,并应用了“每个服务一个数据库”的模式。为了完成订单流程,订单服务首先调用库存管理服务进行库存控制和预留,订单中的相关产品被预留,以防止卖给其他客户。第二步是支付步骤。支付服务负责支付业务。订单服务调用支付服务,从客户的信用卡中完成支付。由于每个服务都是独立的,对分离的数据库的更新在服务范围内被提交。最后一步是创建订单记录。在这一步中,假设发生了技术错误,订单记录无法创建,订单号无法发送给客户,但已从客户那里收到了付款。这里出现了数据一致性问题。接下来我会在文章的“可能的解决方案”部分讨论在这一点之后可以做些什么。

6a76252e7a78be9f98161dfe354b9701.png

1*4IfsBTbf53mszzc44OWwLw.png

可能的解决方案

首先,没有一种单一的解决方案适用于所有情况。根据具体情况,可以采用不同的解决方案。

解决问题有两种主要方法:

分布式事务最终一致性

分布式事务

在分布式事务中,事务在两个或多个资源上执行(例如数据库、消息队列)。通过分布式事务管理器或协调器,跨多个数据库保证数据的完整性。

分布式事务是一个非常复杂的过程,因为涉及多个资源。

两阶段提交(2PC) 是一种阻塞协议,用于保证在分布式事务中所有事务要么全部成功,要么全部失败。

XA标准 是2PC分布式事务的规范。JTA包括Xtandard API。符合JTA标准的应用服务器支持Xtandard API。但所有资源必须部署到单个JTA平台才能运行2PC。对于微服务架构来说,这不太合适。

分布式事务的优点

•强的数据一致性•支持ACID特性

分布式事务的缺点

•维护起来非常复杂•由于是阻塞过程(不适合高负载场景),高延迟和低吞吐量•事务之间可能出现死锁•事务协调器是一个单点故障

最终一致性

最终一致性是分布式系统中用于实现高可用性

的模型。在一个最终一致性的系统中,允许一段时间的不一致,直到解决分布式数据的问题。

这个模型不适用于跨多个微服务的分布式ACID事务。最终一致性使用BASE数据库模型。

虽然ACID模型提供了一个一致的系统,但BASE模型提供了高可用性。

BASE这个缩写代表:

Basically Available:通过在数据库集群的节点之间复制数据来确保数据的可用性•Soft-state:由于缺乏强一致性,数据可能随时间变化。一致性责任委托给开发人员。•Eventual consistency:BASE不可能立即提供一致性,但最终会提供一致性(在短时间内)。

SAGA 是一种操作最终一致性模型的常见模式。

基于协同的SAGA:在这种情况下,不存在中央协调器。每个服务在其任务完成后产生一个事件,并且每个服务监听事件以采取行动。这种模式需要一个成熟的事件驱动架构。•事件溯源:使用事件存储来存储事件变化状态的方法。事件存储是充当事件数据库的消息代理。通过重新播放来自事件存储的事件来重建状态。•基于协同的SAGA模式在事务中步骤较少时可以很好地工作(例如2到4个步骤)。当事务中的步骤数量增加时,很难跟踪哪些服务监听哪些事件。•基于编排的SAGA:协调器服务(Saga执行编排器,SEG)负责根据业务逻辑对事务进行排序。编排器决定应执行哪些操作。如果某个操作失败,编排器会撤销先前的步骤。这称为补偿操作。补偿是在系统保持一致状态时发生故障时要执行的操作。•当数据已被不同的事务更改时,撤销更改可能已经不可能。•补偿必须是幂等的,因为在重试机制中可能会被调用多次。•必须小心设计补偿。

有一些可用的框架可以实现Saga编排模式,例如Camunda、Apache Camel。

SAGA的优点

•在本地原子事务中执行非阻塞操作•事务之间没有死锁•没有单点故障

SAGA的缺点

•最终的数据一致性•没有读隔离,需要额外的努力(例如,用户可能会看到操作已完成,但在几秒钟后由于补偿事务被取消)•当参与服务数量增加时,调试困难•开发成本增加(需要实际服务开发以及补偿服务开发)•设计复杂

在维护分布式数据存储之间的数据一致性可能非常困难。在设计新应用程序时需要有不同的思维方式。我们可以说,数据一致性的责任从数据库转移到了应用程序级别。

选择哪种解决方案

解决方案取决于使用案例和一致性要求。总的来说,应考虑以下设计考虑因素。

1.尽可能避免在微服务之间使用分布式事务。使用分布式事务会带来更复杂的问题。2.设计你的系统,尽可能不要求分布式一致性。为了实现这一点,识别事务边界;•识别必须在同一工作单元中工作的操作。对于这种类型的操作使用强一致性•识别可以容忍一致性方面的可能延迟的操作。对于这种类型的操作使用最终一致性3.考虑使用事件驱动架构进行异步非阻塞服务调用4.通过补偿和协调过程设计容错系统,以保持系统的一致性5.最终一致性模式需要在设计和开发方面进行思维方式的转变

结论

微服务架构具有诸如高可用性、可伸缩性、自动化、自治团队等很多优点。为了最大程度地发挥微服务架构风格的效率,传统方法需要进行一些改变。数据和一致性管理是需要仔细设计的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/205240.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ros报错:The Plugin for class ‘jsk_rviz_plugin/Plotter2D‘ failed to load

一般出现这种情况,是提醒Ros缺少某种库: 图中显示的错误是说明少了jsk_rviz_plugins库,他是一个提供原始rviz插件的包。 解决办法是安装相应的库与插件: #根据自己ROS的版本选择相应的指令 # ubuntu20.04:noetic sudo apt-get i…

幼教智能时代精英论坛北京举行

中国日报11月29日电 近日,智能时代赢之道—2023幼教智能时代精英论坛在北京泰山饭店成功举办,来自全国各地的近百位幼儿园园长、幼教老师集聚一堂,探索智能时代幼教的智慧化解决方案。 伴随“教育数字化战略行动”的深入开展,智慧…

Linux高级IO

文章目录 一.IO的基本概念二.钓鱼五人组三.五种IO模型四.高级IO重要概念1.同步通信 VS 异步通信2.阻塞 VS 非阻塞 五.其他高级IO六.阻塞IO七.非阻塞IO 一.IO的基本概念 什么是IO? I/O(input/output)也就是输入和输出,在著名的冯诺…

python爱心代码高级

在Python中,我们可以使用matplotlib库来创建一个更高级的爱心图形。以下是一个示例: import matplotlib.pyplot as pltimport numpy as npx np.linspace(-2, 2, 1000)y1 np.sqrt(1-(abs(x)-1)**2)y2 -3*np.sqrt(1-(abs(x)/2)**0.5)fig, ax plt.subp…

树与二叉树堆:链式二叉树的实现

目录 链式二叉树的实现: 前提须知: 前序: 中序: 后序: 链式二叉树的构建: 定义结构体: 初始化: 构建左右子树的指针指向: 前序遍历的实现: 中序…

Android String.xml 设置加粗字体/修改字体颜色/动态设置修改文案

之前经常使用Spannable 这次主要在String.xml使用&#xff1a;<![CDATA[和]]> 效果&#xff1a; <resources><string name"str_bianse"><![CDATA[变色 <font color"#ff0000">曲项向天歌</font> 白毛浮绿水]]></st…

Leetcode—266.回文排列【简单】Plus

2023每日刷题&#xff08;四十&#xff09; Leetcode—266.回文排列 C语言实现代码 char chara[26] {0};int calculate(char *arr) {int nums 0;for(int i 0; i < 26; i) {nums arr[i];}return nums; }bool canPermutePalindrome(char* s) {int len strlen(s);for(in…

InstructDiffusion-多种视觉任务统一框架

论文:《InstructDiffusion: A Generalist Modeling Interface for Vision Tasks》 github&#xff1a;https://github.com/cientgu/InstructDiffusion InstructPix2Pix&#xff1a;参考 文章目录 摘要引言算法视觉任务统一引导训练集重构统一框架 实验训练集关键点检测分割图像…

Vue3的项目创建到启动

Vue3的项目创建 检查node版本创建 npm init vuelatest 安装依赖 项目启动 启动成功

OpenAI再次与Sam Altman谈判;ChatGPT Voice正式上线

11月22日&#xff0c;金融时报消息&#xff0c;OpenAI迫于超过700名员工联名信的压力&#xff0c;再次启动了与Sam Altman的谈判&#xff0c;希望他回归董事会。 在Sam确定加入微软后&#xff0c;OpenAI超700名员工签署了一封联名信&#xff0c;要求Sam和Greg Brockman&#x…

Spring---对象的存储和读取

文章目录 Spring对象的存储创建Bean对象将Bean对象存储到spring中添加配置文件存储Bean对象 Spring对象的读取得到Spring上下文对象从Spring中取出Bean对象使用Bean对象 Spring对象的存储 创建Bean对象 Bean对象其实就是一个普通的Java对象。我们按照创建Java对象的方式来创建…

【云原生】什么是 Kubernetes ?

什么是 Kubernetes &#xff1f; Kubernetes 是一个开源容器编排平台&#xff0c;管理着一系列的 主机 或者 服务器&#xff0c;它们被称作是 节点&#xff08;Node&#xff09;。 每一个节点运行了若干个相互独立的 Pod。 Pod 是 Kubernetes 中可以部署的 最小执行单元&#x…

USB驱动开发基础

USB标准 USB1.0&#xff0c; 1996&#xff0c;低速1.5Mbps和高速12Mbps&#xff0c;USB1.1 iMac G3&#xff0c;Type A和Type B接口USB 2.0 2000&#xff0c; 480Mpbs&#xff0c;Type A/B/C接口、Micro A/BUSB 3.0 5Gbps, 随着USB 3.2命名规定&#xff0c;现在也叫USB 3.2 Ge…

Linux网络——数据链路层

目录 一.认识以太网 二.以太网帧格式 三.认识MAC地址 四.认识MTU 五.以太局域网的通信原理 六.其他重要协议 1.DNS协议 2.域名简介 3.ICMP协议 4.NAT技术 5.NAT技术的缺陷 6.NAT和代理服务器 一.认识以太网 "以太网" 不是一种具体的网络, 而是一种技术标…

docker (简介、dcoker详细安装步骤、容器常用命令)一站打包- day01

一、 为什么出现 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build&#xff0c;Ship and Run Any App,Anywhere”&#xff0c;也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP&#xff08;可以是一个WEB应用或数据库应…

数据库的重要你了解多少?如何保障数据库的安全?

随着信息技术的快速发展&#xff0c;数据库已经成为企业、组织以及个人日常生活中不可或缺的一部分。然而&#xff0c;随着数据库的广泛应用&#xff0c;其安全性问题也日益凸显。数据库的安全性主要包括数据的完整性、保密性和可用性。本文将探讨数据库安全性的重要性、以及如…

常使用的定时任务

常使用的定时任务 一、 linux自带的定时任务 1、crontab 有这样一个需求&#xff1a;我们使用Java写一个工具jar包在系统空闲的时候去采集已经部署在Linux系统上的项目的一 些数据&#xff0c;可以使用 linux 系统的 crontab。 运行crontab -e&#xff0c;可以编辑定时器&…

C语言——深入理解指针(3)

目录 1. 字符指针 2. 数组指针 2.1 数组指针变量 2.2 数组指针变量的初始化 3.二维数组传参&#xff08;本质&#xff09; 4. 函数指针 4.1 函数指针变量的创建 4.2 函数指针的使用 4.3 typedef 5. 函数指针数组 6. 转移表&#xff08;函数指针数组的使用&#xff…

sqli-labs(7)

32. 看到“前面有了\这里使用宽字节注入 当字符的大小为一个字节时为窄字节 当字符的大小为两个字节时为宽字节 英文字符的大小为一个字节&#xff0c;汉字为两个 漏洞产生的成因在sql中使用像GB2312,GBK,GB18030,BIG5,Shift_JIS这些宽字节编码而php使用utf-8编码 为了防止注…

token认证机制,基于JWT的Token认证机制实现,安全性的问题

文章目录 token认证机制几种常用的认证机制HTTP Basic AuthOAuthCookie AuthToken AuthToken Auth的优点 基于JWT的Token认证机制实现JWT的组成认证过程登录请求认证 对Token认证的五点认识JWT的JAVA实现 基于JWT的Token认证的安全问题确保验证过程的安全性如何防范XSS Attacks…