立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 494|回复: 5

[分享] CAP 理论常被解释为一种“三选二”定律,这是否是一种误解?

[复制链接]
发表于 2024-11-7 17:53 | 显示全部楼层 |阅读模式

登陆有奖并可浏览互动!

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录 手机动态码快速登录

×
此处的 CAP 理论指的是计算机科学中分布式系统领域的一条已经证明的定律。参见:
CAP theorem - Wikipedia
我对这个定律的证明没有疑虑。但现实生活中,大部分人解释这一定律时,常常简单的表述为:“一致性、可用性、分区容忍性三者你只能同时达到其中两个,不可能同时达到”
这是否符合 CAP 定律的本意?这样的描述是否存在误解?
谢谢每一位回答者。

原文地址:https://www.zhihu.com/question/64778723
楼主热帖
回复

使用道具 举报

发表于 2024-11-7 17:54 | 显示全部楼层
不是误解。
很多答主把 “分布式系统” 理解得太狭隘了,于是认为既然是讨论分布式系统,那么 P (也就是分区容忍性)一定不能舍弃。
实际上这里对 “分布式系统” 的理解完全可以更广泛,比如一颗多核CPU,从微观的尺度上你也可以把它看作分布式系统来分析。一个通过可靠网络连接起来的超算,它的很多性质也可以当作分布式系统来分析。 那么在设计这类系统的时候,我们通常都是假设参与运算的各个单元之间的通讯(CPU的总线,超算机房里的网线)都是可靠的,这事实上就是舍弃了 P(分区容忍性)而选择了 A(可用性)和 C(一致性)。
另一种认为「对CAP理论的朴素理解」是误解的误解是:因为有 “最终一致性” 这样的选择,所以一致性不是非黑即白的。这事实上也是不对的,实际上所谓的 “最终一致” 就是在发生网络分区的时候,抛弃了 C 选择了 A,至于在网络故障恢复之后把 C 再捡起来,这改变不了系统在某些工况下放弃了对 C 的保证的事实。

关于上述观点,我引用一下wiki来佐证




看最后一段话,我给翻译翻译:“大家常说的“三选二”概念可能会误导人,因为系统设计者只有在发生网络分区的时候才需要在一致性和可用性之间做牺牲,但在很多系统里分区是非常少见的。”
大家注意,我们讨论CAP讨论的都是一种「保证」(guarantees),而不是工况。
理论的提出者所讨论的 “放弃C” 原本就是指 “当发生网络分区的情况时”,这时候放弃了一致性,那么就是没提供对 C的保证。
所以所谓的 “最终一致” 的系统,其实就是一种 AP 系统,只不过它用一个新概念把自己从其他 AP 系统里区分了出来,取了个好听的名字,便于营销罢了。 当然我也不否认这种细分有其积极意义,只是既然是学习理论,就老老实实学习理论,不要被新概念忽悠瘸了就好。
回复 支持 反对

使用道具 举报

发表于 2024-11-7 17:54 | 显示全部楼层
三选二是没问题的,要真正了解到 CAP 的定义,才能明白为什么三选二。
1. CAP理论

1.1 CAP 理论概述

CAP 理论是分布式系统的基础原则,它包涵了 Consistency 一致性Availability 可用性 以及 Partition-tolerance 分区容错性 三个特性。



CAP 理论

Consistency 一致性
简单来说,写入数据到分布式系统的某一个节点后,操作会立刻反应到整个分布式系统上。即任何时刻从任意一个节点读取的值都必须是一样的。
要实现一致性,那么需要保证:当在分布式系统更新一个节点的数据时候,分布式系统会立马把这个数据同步到所有的节点上。要么所有节点都更新数据,要么都不更新。始终保持所有节点数据一致。
并且在这个数据同步期间,分布式系统不能对外提供服务,否则会违背一致性(因为可能会访问到尚未同步的节点,此时读到的数据就不一致了)。
举个例子,当对节点 A 执行操作 set x = 1; 之后,x 的新值会立刻同步到所有的节点上,保证所有的节点上 x 值都被更新为 1。

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

Partition-tolerance 分区容错性:
当分布式系统中有节点通信意外中断时,分布式系统会被分为几个区域。此时对于每一个区域都能正常对外提供服务,分布式系统仍然能正常运行。
另外我们都听过,在分布式系统中 CAP 三个特性是无法同时满足的。

1.2 为什么说 CAP 不能同时满足?

我们都听过分布式系统中 CAP 是无法同时满足的,但是很多时候都是云里雾里的模糊概念,而没有去深究。就从一个简单例子说起吧。
有一个很简单的程序,就存了几个键值对。我们在多台机器上都部署这个程序,整体对外提供服务,这就成了一个简单的分布式系统。每一个运行的程序称为一个节点,如图所示:



分布式系统示例

此时,某个客户端 Client1 连接了节点 A,向节点 A 发起请求: SET a = 999
然后某个客户端 Client2 连接了节点 B,发送请求:GET a; 立马读取 a 的值。

先假设现在我们要满足 Consistency 一致性。前面提过,需要保证:当在分布式系统更新一个节点的数据时候,分布式系统会立马把这个数据同步到所有的节点上。要么所有节点都更新数据,要么都不更新。始终保持所有节点数据一致。
怎么保证这一点呢?有两个方案:
方案一:数据全部都只存放在一个节点上。其他节点全部从这个节点上读取数据。
很容易理解,所有数据都在一个节点上,那么就根本不需要 "把数据同步到其他节点"  这一步操作了,其他所有节点读写数据请求都会被转发到这个节点上来执行。所以它一定满足 Consistency 一致性。
在这个例子中即只有 节点 A 保存了所有数据,其他节点数据全是空的,Client2 的请求会被转发到节点 A 上,因此得到的 a 都是 999一致性得到保证。



CA

另外,由于只有一份数据,没有数据同步这一步骤,因此分布式系统在任何时间都是能对外提供服务的。下一个请求能够立马得到成功的响应。所以 Availability 可用性 也是满足的。
然而,这个系统满足 Partition-tolerance 分区容错性 吗? 遗憾的是并不满足:
很简单,因为数据全部存在节点 A 上。假设节点 B节点 A 的网络通信因为某种原因中断了(这是很有可能的),此时发生分区节点 B 就无法对外提供服务了,因为他无法从节点 A 拿到数据。这违背了分区容错性的定义。所以不满足分区容错性
综上,这个系统满足 Consistency 一致性 和  Availability 可用性,但是不满足 Partition-tolerance 分区容错性。这属于 CA

方案二:每个节点都存放数据。
在这种方案下,要保证一致性,那么必须要将数据修改立刻同步到每一个节点。然而同步数据总得需要时间,在这个时间段内,分布式系统不能对外响应,否则会违背一致性
当在节点 A 执行 SET a = 999 的操作后,节点 A 需要将这个操作同步到其他的节点上,保证数据的一致性。



CP

Consistency 一致性 满足之后,每个节点都是完全相同的数据备份。此时就算某个节点 A 与其他节点的通信中断,此时产生了两个分区 单独的节点A 是一个分区, 其他所有节点 是另外一个分区。但是这两个分区都有完整的数据,因此都可以对外提供服务。也就是说满足了 Partition-tolerance 分区容错性
可用性满足吗?并不。
在节点数据同步的过程中,整个分布式系统不能对外提供服务。因此在这个过程中的请求都无法得到响应,所以 Availability 可用性 无法满足Client2 的请求会超时,而不是立马返回成功,因此可用性不成立。
综上,这个属于 CP

另外,假设我不选择 Consistency 一致性 的时候,能同时满足 Availability 可用性 Partition-tolerance 分区容错性 吗?
可以。 因为不需要满足一致性了,实际上每个节点的数据都有自己的副本,但是这些副本的值并不一定完全相同,因为没有数据同步。对于 Client1 来说 GET a 得到的是 999. 而对于 Client2 来说 GET a 是 1。
此时就算发生网络分区,每个节点都还是能对外服务的。所以满足 Partition-tolerance 分区容错性。
而且任一时刻的请求也能正常得到响应,因为没有数据同步的过程,自然任何时候都能处理请求了,所以也满足 Availability 可用性。这个就是 AP。



AP

至此,我们已经可以得到结论。分布式系统中 CAP 三者是不能完全同时满足的,只能够3选2了。。
通常,在分布式系统中 Partition-tolerance 分区容错性 是我们不得不选择的。 很容易理解,不选择分区容错性,就等于数据只放在一个节点A上。那这个分布式系统的意义好像也不大,搞来搞去鸡蛋还是放在一个篮子里了。这个节点 A一旦挂了整个系统毫无疑问直接挂掉,这对生产环境来说通常是难以接受的。
所以,既然选择了 P,那剩下就要在 A 和 C 之间进行一个抉择了。
回复 支持 反对

使用道具 举报

发表于 2024-11-7 17:54 | 显示全部楼层
CAP定理:指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得。
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时)               
可用性(A):负载过大后,集群整体是否还能响应客户端的读写请求。(服务一直可用,而且是正常响应时间)
分区容错性(P):分区容忍性,就是高可用性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,越多机器越好)
                CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡

C A 满足的情况下,P不能满足的原因:
        数据同步(C)需要时间,也要正常的时间内响应(A),那么机器数量就要少,所以P就不满足
CP 满足的情况下,A不能满足的原因:
        数据同步(C)需要时间, 机器数量也多(P),但是同步数据需要时间,所以不能再正常时间内响应,所以A就不满足
AP 满足的情况下,C不能满足的原因:
        机器数量也多(P),正常的时间内响应(A),那么数据就不能及时同步到其他节点,所以C不满足

使用场景 注册中心选择:
        Zookeeper:CP设计,保证了一致性,集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足
        Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化

结论:分布式系统中P,肯定要满足,所以只能在CA中二选一
        没有最好的选择,最好的选择是根据业务场景来进行架构设计
        如果要求一致性,则选择zookeeper,如金融行业                       
        如果要去可用性,则Eureka,如电商系统
回复 支持 反对

使用道具 举报

发表于 2024-11-7 17:55 | 显示全部楼层
是误解,一般来说 P 是前提。所以基本是CA里选,不是任意3选2.
为什么呢?
P 意指分区容忍性。 这个分区容忍性什么意思,很多人容易望文生义,不要见风就是雨,理解成别的什么意思。所谓分区指的是网络分区的意思,这个一样还是容易望文生义。详细一点解释,比如你有A B两台服务器,它们之间是有通信的,突然,不知道为什么,它们之间的网络链接断掉了。好了,那么现在本来AB在同一个网络现在发生了网络分区,变成了A所在的A网络和B所在的B网络。所谓的分区容忍性,就是说一个数据服务的多台服务器在发生了上述情况的时候,依然能继续提供服务。
所以显而易见的,P是大前提,如果P发生了,咱们的数据服务直接不服务了,还谈个毛的可用性和一致性呢。
因此CAP要解释成,当P发生的时候,A和C只能而选一。
举个简单的例子,A服务器B服务器同步数据,现在A B之间网络断掉了,那么现在发来A一个写入请求,但是B却没有相关的请求,显然,如果A不写,保持一致性,那么我们就失去了A的服务,但是如果A写了,跟B的数据就不一致了,我们自然就丧失了一致性。
这里设计就涉及到架构师的选择了。注意这里的一致性是强一致性,意思是AB的数据时刻都是同步的,如果我们放弃了强一致性,不代表我们的数据就是一定是不一致的了,我们可以让A先写入本地,等到通信恢复了再同步给B,这就是所谓的最终一致性,长远的看我们的数据还是一致的,我们只是在某一个时间窗口里数据不一致罢了。如果这个时间窗口小过了用户逻辑处理的时间。那么其实对于用户来说根本毛都感觉不到。
最终一致性有个很有意思的协议叫gossip就跟传八卦一个意思,我就把我收到里信息里我本地没有的部分加到我本地,再把这个信息发出去,那么长远的看,网络时好时坏,但是最终所有人都会有所有的信息。因此我们还是能够保证数据的最终一致性的。
综上,CAP应该描述成,当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能2选1。
回复 支持 反对

使用道具 举报

发表于 2024-11-7 17:56 | 显示全部楼层
是的,这是一种误解。注意 CAP 定律的完整表述:Any networked shared-data system can have at most two of the three desired properties.
换句话说, CAP 定律的前提是 P,当 P 决定后才有 CA 的抉择。因此,简单粗暴地说「三选二」是有一定误导性的。
其实这个问题早在 2012 年就已经被详细解释过了[1],这里已经说得很好了,下面是引用[2]:
为什么“三选二”公式有误导性

理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。一般来说跨区域的系统,设计师无法舍弃P性质,那么就只能在数据一致性和可用性上做一个艰难选择。不确切地说,NoSQL运动的主题其实是创造各种可用性优先、数据一致性其次的方案;而传统数据库坚守ACID特性(原子性、一致性、隔离性、持久性),做的是相反的事情。下文“ACID、BASE、CAP”小节详细说明了它们的差异。
事实上,CAP理论本身就是在类似的讨论中诞生的。早在1990年代中期,我和同事构建了一系列的基于集群的跨区域系统(实质上是早期的云计算),包括搜索引擎、缓存代理以及内容分发系统。从收入目标以及合约规定来讲,系统可用性是首要目标,因而我们常规会使用缓存或者事后校核更新日志来优化系统的可用性。尽管这些策略提升了系统的可用性,但这是以牺牲系统数据一致性为代价的。
关于“数据一致性 VS 可用性”的第一回合争论,表现为ACID与BASE之争。当时BASE还不怎么被人们接受,主要是大家看重ACID的优点而不愿意放弃。提出CAP理论,目的是证明有必要开拓更广阔的设计空间,因此才有了“三选二”公式。CAP理论最早在1998年秋季提出,1999年正式发表,并在2000年登上Symposium on Principles of Distributed Computing大会的主题演讲,最终确立了该理论的正确性。
“三选二”的观点在几个方面起了误导作用。首先,由于分区很少发生,那么在系统不存在分区的情况下没什么理由牺牲C或A。其次,C与A之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,乃至因为牵涉到特定的数据或用户而有所不同。最后,这三种性质都可以在程度上衡量,并不是非黑即白的有或无。可用性显然是在0%到100%之间连续变化的,一致性分很多级别,连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。
要探索这些细微的差别,就要突破传统的分区处理方式,而这是一项根本性的挑战。因为分区很少出现,CAP在大多数时候允许完美的C和A。但当分区存在或可感知其影响的情况下,就要预备一种策略去探知分区并显式处理其影响。这样的策略应分为三个步骤:探知分区发生,进入显式的分区模式以限制某些操作,启动恢复过程以恢复数据一致性并补偿分区期间发生的错误。

进一步阅读
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录 手机动态码快速登录

本版积分规则

关闭

官方推荐 上一条 /3 下一条

快速回复 返回列表 客服中心 搜索 官方QQ群 洽谈合作
快速回复返回顶部 返回列表