【分布式】CAP理论详解

一、CAP理论概述

在分布式系统中,CAP是指一组原则,它们描述了在网络分区(Partition)时,分布式系统能够提供的保证。CAP代表Consistency(一致性)、Availability(可用性)和Partition Tolerance(分区容错性)。

麻省理工学院的 Seth Gilbert 和 Nancy Lynch 以严谨的数学推理证明了 CAP 猜想。自此,CAP 正式从猜想变为分布式计算领域所公认的著名定理。这个定理里描述了一个分布式的系统中,涉及共享数据问题时,以下三个特性最多只能同时满足其中两个。

1.1、一致性(Consistency)

一致性(Consistency):代表数据在任何时刻、任何分布式节点中所看到的都是符合预期的。

简单来说,写入数据到分布式系统的某一个节点后,操作会立刻反应到整个分布式系统上。即任何时刻从任意一个节点读取的数据都必须是一样的。

要实现一致性,那么需要保证:当在分布式系统更新一个节点的数据时候,分布式系统会立马把这个数据同步到所有的节点上。要么所有节点都更新数据,要么都不更新。始终保持所有节点数据一致。

并且在这个数据同步期间,分布式系统不能对外提供服务,否则会违背一致性(因为可能会访问到尚未同步的节点,此时读到的数据就不一致了)。

举个例子,当对节点 A 执行操作 set x = 1; 之后,x 的新值会立刻同步到所有的节点上,保证所有的节点上 x 值都被更新为 1。

1.2、可用性(Availability)

可用性(Availability):代表系统不间断地提供服务的能力。

即任何时刻对于分布式系统节点的访问都会返回成功的结果,而不会是超时或者失败。可用性强调的是一定能读到数据,至于读取到的数据是新值还是旧值都不影响,但一定要能成功访问。

1.3、分区容忍性(Partition Tolerance)

分区容忍性(Partition Tolerance):代表分布式系统在面对网络分区(Network Partition)时仍然能够正常运行的能力。网络分区是指系统中的节点之间无法互相通信或通信延迟非常高的情况。

在分布式系统中,由于网络的不可靠性和不稳定性,网络分区是常见的情况。例如,一个由多个节点组成的分布式系统可能由于网络故障、服务器故障或网络拥塞等原因导致节点之间无法彼此通信。

分区容错性的目标是使分布式系统能够在网络分区的情况下仍然保持运行和提供服务。这意味着即使网络分区发生,系统的各个节点仍然能够正常处理请求、进行数据读写操作,并向用户提供结果。

二、为什么说CAP不能同时满足

2.1、举例一

我们都听过分布式系统中 CAP 是无法同时满足的,但是很多时候都是只有一个模糊概念,所以我就从一个简单例子说起吧。

有一个很简单的程序,就存了几个键值对。我们在多台机器上都部署这个程序,整体对外提供服务,这就成了一个简单的分布式系统。每一个运行的程序称为一个节点,如图所示:

此时,某个客户端 Client1 连接了节点 A,向节点 A 发起请求: SET a = 999

然后某个客户端 Client2 连接了节点 B,发送请求:GET a; 立马读取 a 的值。

先假设现在我们要满足 Consistency 一致性。前面提过,需要保证:当在分布式系统更新一个节点的数据时候,分布式系统会立马把这个数据同步到所有的节点上。要么所有节点都更新数据,要么都不更新。始终保持所有节点数据一致。

怎么保证这一点呢?有两个方案:

方案一:数据全部都只存放在一个节点上。其他节点全部从这个节点上读取数据。

很容易理解,所有数据都在一个节点上,那么就根本不需要 "把数据同步到其他节点" 这一步操作了,其他所有节点读写数据请求都会被转发到这个节点上来执行。所以它一定满足Consistency一致性。

在这个例子中即只有节点 A保存了所有数据,其他节点数据全是空的,Client2的请求会被转发到节点 A 上,因此得到的a 都是 999一致性得到保证。

另外,由于只有一份数据,没有数据同步这一步骤,因此分布式系统在任何时间都是能对外提供服务的。下一个请求能够立马得到成功的响应。所以 Availability 可用性 也是满足的。

然而,这个系统满足 Partition-tolerance 分区容错性 吗? 遗憾的是并不满足:

很简单,因为数据全部存在节点 A 上。假设节点 B节点 A 的网络通信因为某种原因中断了(这是很有可能的),此时发生分区节点 B 就无法对外提供服务了,因为他无法从节点 A 拿到数据。这违背了分区容错性的定义。所以不满足分区容错性

综上,这个系统满足 Consistency 一致性Availability 可用性,但是不满足 Partition-tolerance 分区容错性。这属于 CA

方案二:每个节点都存放数据。

在这种方案下,要保证一致性,那么必须要将数据修改立刻同步到每一个节点。然而同步数据总得需要时间,在这个时间段内,分布式系统不能对外响应,否则会违背一致性

当在节点 A 执行 SET a = 999 的操作后,节点 A 需要将这个操作同步到其他的节点上,保证数据的一致性。

Consistency 一致性 满足之后,每个节点都是完全相同的数据备份。此时就算某个节点 A 与其他节点的通信中断,此时产生了两个分区 单独的节点A 是一个分区, 其他所有节点 是另外一个分区。但是这两个分区都有完整的数据,因此都可以对外提供服务。也就是说满足了 Partition-tolerance 分区容错性

可用性满足吗?并不。

在节点数据同步的过程中,整个分布式系统不能对外提供服务。因此在这个过程中的请求都无法得到响应,所以 Availability 可用性 无法满足Client2 的请求会超时,而不是立马返回成功,因此可用性不成立。

综上,这个属于 CP

另外,假设我不选择 Consistency 一致性 的时候,能同时满足 Availability 可用性Partition-tolerance 分区容错性 吗?

可以。 因为不需要满足一致性了,实际上每个节点的数据都有自己的副本,但是这些副本的值并不一定完全相同,因为没有数据同步。对于 Client1 来说 GET a 得到的是 999. 而对于 Client2 来说 GET a 是 1。

此时就算发生网络分区,每个节点都还是能对外服务的。所以满足 Partition-tolerance 分区容错性

而且任一时刻的请求也能正常得到响应,因为没有数据同步的过程,自然任何时候都能处理请求了,所以也满足 Availability 可用性。 这个就是 AP

至此,我们已经可以得到结论。分布式系统中 CAP 三者是不能完全同时满足的,只能够3选2了

通常,在分布式系统中 Partition-tolerance 分区容错性 是我们不得不选择的。 很容易理解,不选择分区容错性,就等于数据只放在一个节点A上。那这个分布式系统的意义好像也不大,搞来搞去鸡蛋还是放在一个篮子里了。这个节点 A一旦挂了整个系统毫无疑问直接挂掉,这对生产环境来说通常是难以接受的。

2.2、举例二

单纯只列概念,CAP 是比较抽象的。假设 蔚来商城 的服务拓扑如图所示,一个来自最终用户的交易请求,将交由账号、商家和仓库服务集群中某一个节点来完成响应:

在这套系统中,每一个单独的服务节点都有自己的数据库,假设某次交易请求分别由“账号节点 1”、“商家节点 2”、“仓库节点 N”联合进行响应。当用户购买一件价值 100 元的商品后,账号节点 1 首先应给该用户账号扣减 100 元货款,它在自己数据库扣减 100 元很容易,但它还要把这次交易变动告知本集群的节点 2 到节点 N,并要确保能正确变更商家和仓库集群其他账号节点中的关联数据,此时将面临以下可能的情况。

  • 如果该变动信息没有及时同步给其他账号节点,将导致有可能发生用户购买另一商品时,被分配给到另一个节点处理,由于看到账号上有不正确的余额而错误地发生了原本无法进行的交易,此为一致性问题。

  • 如果由于要把该变动信息同步给其他账号节点,必须暂时停止对该用户的交易服务,直至数据同步一致后再重新恢复,将可能导致用户在下一次购买商品时,因系统暂时无法提供服务而被拒绝交易,此为可用性问题。

  • 如果由于账号服务集群中某一部分节点,因出现网络问题,无法正常与另一部分节点交换账号变动信息,此时服务集群中无论哪一部分节点对外提供的服务都可能是不正确的,整个集群能否承受由于部分节点之间的连接中断而仍然能够正确地提供服务,此为分区容忍性。

以上还仅仅涉及了账号服务集群自身的 CAP 问题,对于整个 Fenix's Bookstore 站点来说,它更是面临着来自于账号、商家和仓库服务集群带来的 CAP 问题,譬如,用户账号扣款后,由于未及时通知仓库服务中的全部节点,导致另一次交易中看到仓库里有不正确的库存数据而发生超售。又譬如因涉及仓库中某个商品的交易正在进行,为了同步用户、商家和仓库的交易变动,而暂时锁定该商品的交易服务,导致了的可用性问题,等等。

三、舍弃 C、A、P 时所带来的不同影响

由于 CAP 定理已有严格的证明,来分析如果舍弃 C、A、P 时所带来的不同影响。

  • 如果放弃分区容忍性(CA without P),意味着我们将假设节点之间通信永远是可靠的。永远可靠的通信在分布式系统中必定不成立的,这不是你想不想的问题,而是只要用到网络来共享数据,分区现象就会始终存在。在现实中,最容易找到放弃分区容忍性的例子便是传统的关系数据库集群,这样的集群虽然依然采用由网络连接的多个节点来协同工作,但数据却不是通过网络来实现共享的。

  • 如果放弃可用性(CP without A),意味着我们将假设一旦网络发生分区,节点之间的信息同步时间可以无限制地延长,此时,问题相当于退化到前面“全局事务”中讨论的一个系统使用多个数据源的场景之中,我们可以通过 2PC/3PC 等手段,同时获得分区容忍性和一致性。

  • 如果放弃一致性(AP without C),意味着我们将假设一旦发生分区,节点之间所提供的数据可能不一致。选择放弃一致性的 AP 系统目前是设计分布式系统的主流选择,因为 P 是分布式网络的天然属性,你再不想要也无法丢弃;而 A 通常是建设分布式的目的,如果可用性随着节点数量增加反而降低的话,很多分布式系统可能就失去了存在的价值,除非银行、证券这些涉及金钱交易的服务,宁可中断也不能出错,否则多数系统是不能容忍节点越多可用性反而越低的。目前大多数 NoSQL 库和支持分布式的缓存框架都是 AP 系统,以 Redis 集群为例,如果某个 Redis 节点出现网络分区,那仍不妨碍各个节点以自己本地存储的数据对外提供缓存服务,但这时有可能出现请求分配到不同节点时返回给客户端的是不一致的数据。

到这里,不知道你是否对“选择放弃一致性的 AP 系统目前是设计分布式系统的主流选择”这个结论感到一丝无奈,“事务”原本的目的就是获得“一致性”,而在分布式环境中,“一致性”却不得不成为通常被牺牲、被放弃的那一项属性。但无论如何,我们建设信息系统,终究还是要确保操作结果至少在最终交付的时候是正确的,这句话的意思是允许数据在中间过程出错(不一致),但应该在输出时被修正过来。

总之适合业务场景的方案才是最好的方案。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java 进阶篇】JQuery 案例:全选全不选,为选择添彩

在前端的舞台上,用户交互是一场精彩的表演,而全选全不选的功能则是其中一段引人入胜的剧情。通过巧妙运用 JQuery,我们可以为用户提供便捷的全选和全不选操作,让页面更富交互性。本篇博客将深入探讨 JQuery 中全选全不选的实现原理…

<MySQL> 查询数据进阶操作 -- 聚合查询

目录 一、聚合查询概述 二、聚合函数查询 2.1 常用函数 2.2 使用函数演示 2.3 聚合函数参数为*或列名的查询区别 2.4 字符串不能参与数学运算 2.5 具有误导性的结果集 三、分组查询 group by 四、分组后条件表达式查询 五、MySQL 中各个关键字的执行顺序 一、聚合查询…

232.用栈实现队列(LeetCode)

思路 思路:利用两个栈实现队列先进先出的特性,先将元素导入一个栈内 模拟出队时,则将所有元素导入另一个栈内,此时元素顺序被反转过来,只需要取栈顶数据即可 那我们就可以将两个栈的功能分开,一个专门入pus…

多机器人群体的任务状态与机器人状态同步设计思路

背景技术 近年来,随着科学技术的发展需要,机器人技术不断进步。面临任务的日益复杂化,单机器人在很多环境下已经无法满足生产要求,于是国内外科研工作者对多机器人技术投入了大量关注,提出了利用多机器人协作来代替单机…

Karmada更高效地实现故障转移

随着云原生技术的发展,其应用场景不断扩大。越来越多的企业开始将应用程序部署在 Kubernetes 集群中,随着 Kubernetes 集群规模的不断扩大,也带来了许多管理挑战,例如多集群间负载均衡、资源调度、故障转移等问题。为了解决这些问…

【Python】上市公司数据进行经典OLS回归实操

一、题目二、数据合并、清洗、描述性统计1、数据获取2、数据合并3、选择董监高薪酬作为解释变量的理论逻辑分析 三、多元回归模型的参数估计、结果展示与分析1、描述性统计分析2、剔除金融类上市公司3、对所有变量进行1%缩尾处理4、0-1标准化,所有解释变量5、绘制热…

网络运维Day16

文章目录 Docker简介什么是容器命名空间: Docker 的优缺点 Docker安装Docker镜像管理什么是镜像镜像管理 Docker容器管理运行容器容器启动、停止、重启拷贝文件进入容器容器与应用 DockerfileDockerfile 语法案例 总结 Docker简介 什么是容器 容器是用来装东西的&a…

磁带标签设计:Tape Label Studio 2023.11.0.7 Crack

Tape Label Studio(磁带标签设计) 为标签创建颜色样式。修改标签中使用的每种颜色,包括背景、条形码、边框、文本和字符颜色。自定义边框样式以适合您正在使用的标签。从实心、虚线或虚线边框中进行选择。轻松调整宽度和宽度。Tape Label St…

【网络奇缘】- 计算机网络|网络类型|性能指标

🌈个人主页: Aileen_0v0🔥系列专栏: 一见倾心,再见倾城 --- 计算机网络~💫个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分类 1.根据范围分类 ​编辑 2.按使用者分​编辑 3.按交换技术分 ​编辑4.按拓扑结构分 ​…

react中间件的理解

一、是什么? 中间件(Middleware)在计算机中,是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络应用上的各个部分或不同的应用,能…

Netty Review - 从BIO到NIO的进化推演

文章目录 BIODEMO 1DEMO 2小结论单线程BIO的缺陷BIO如何处理并发多线程BIO服务器的弊端 NIONIO要解决的问题模拟NIO方案一: (等待连接时和等待数据时不阻塞)方案二(缓存Socket,轮询数据是否准备好)方案二存…

225.用队列实现栈(LeetCode)

思路 思路:用两个队列实现栈后进先出的特性 ,两个队列为空时,先将数据都导向其中一个队列。 当要模拟出栈时,将前面的元素都导入另一个空队列,再将最后一个元素移出队列 实现 实现: 因为C语言没有库可以…

网络运维Day17

文章目录 什么是数据库MySQL介绍实验环境准备构建MySQL服务连接数据库修改root密码 数据库基础常用的SQL命令分类SQL命令使用规则MySQL基本操作创建库创建表查看表结构 记录管理命令 数据类型数值类型 数据类型日期时间类型时间函数案例枚举类型 约束条件案例修改表结构添加新字…

C++实现ransac

目录 一、ransac算法原理 1.1、算法概念 1.2、图解 二、c实现ransac 2.1、设置随机样本和离群点 2.2、随机抽取样本 2.3、内点计算 2.4、更新参数 2.2、完整代码 一、ransac算法原理 1.1、算法概念 随机抽样一致性 (RANSAC) 是一种迭代方法,用于根据一组包…

【Java 进阶篇】JQuery DOM操作:CRUD操作的前端魔法

在前端开发的舞台上,CRUD(Create, Read, Update, Delete)操作是一种极为重要的技能,它涉及对页面元素的增删改查。而JQuery,这位前端开发的魔法师,为我们提供了便捷而强大的方法,使得CRUD操作变…

IP地址如何实现定位功能?

网络犯罪、保护网络安全的重要手段。近日,一则新闻引起了广大网友的关注:IP也能实现定位功能,这是如何做到的呢?本文将对此进行深入解析。 首先,我们需要了解什么是IP地址定位。IP地址定位是通过IP地址确定网络用户所在…

【Windows 开发环境配置——NVIDIA 篇】CUDA、cuDNN、TensorRT 三件套安装

CUDA 从CUDA Toolkit Archive下载相应版本的离线安装包,这里以11.7为例。 打开安装包,在安装选项选择自定义模式,点击下一步。 在自定义安装选项中,仅选择CUDA组件(其中Nsight相关组件用于代码调试与性能分析&#xff…

Linux--线程概念+线程控制

1.什么是线程 相对于进程而言,进程是承担资源调度的实体,线程在进程内部运行,是操作系统调度的基本单位。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列…

Qt QWebEngine 加载网页及交互,实现C++与JS 相互调用

目录 前言1、QtWebEngine介绍2、安装3、核心类介绍3.1 QWebEngineView3.2 QWebEnginePage3.3 QWebEngineProfile3.4 QWebEngineHistory3.5 QWebEngineSettings 4、加载网页5、C调用JS5.1 无返回值5.2 有返回值 6、JS调用C6.1 新建WebObject 类继承自QObject。6.2 将WebObject对…

Day30力扣打卡

打卡记录 最长回文子序列(区间DP) 链接 class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)f [[0] * n for _ in range(n)]max lambda x, y: x if x > y else yfor i in range(n - 1, -1, -1):f[i][i] 1for j in ra…