立即注册找回密码

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

手机动态码快速登录

手机号快速注册登录

搜索

图文播报

查看: 947|回复: 5

[分享] 如何深入理解 CAP 理论和适用场景?

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

使用道具 举报

发表于 2024-11-4 20:20 | 显示全部楼层
一、背景

随着互联网规模和用户需求的不断增长,分布式系统成为构建大规模应用的必然选择。在分布式系统中,数据和计算资源被分散在多个节点上,带来了许多挑战。其中一个关键问题是如何在网络分区或故障情况下保持一致性和可用性。CAP理论由Eric Brewer于2000年提出,帮助我们理解在分布式系统中这三个重要特性之间的取舍。
二、CAP理论的原理



CAP理论指出,在一个分布式系统中,不可能同时满足以下三个属性:

  • 一致性(Consistency):所有节点在同一时刻是否看到相同的数据视图。
  • 可用性(Availability):每个请求是否都能在有限的时间内得到响应,不保证返回最新的数据。
  • 分区容错性(Partition Tolerance):即使在网络分区的情况下,系统仍能继续工作。
三、CAP理论的应用

在实际应用中,根据系统需求和业务场景,我们需要根据CAP理论权衡这三个属性。不同的系统可以在以下方式中进行选择:

  • CA系统:在一些传统的关系型数据库系统中,一致性和可用性被认为是首要考虑的,而分区容错性则相对较弱。这意味着在网络分区发生时,系统会选择阻塞请求以保持数据的一致性,以确保所有节点看到的数据是相同的。这对于某些数据的强一致性需求很重要,但可能导致系统整体的可用性降低。典型代表如MySQL和PostgreSQL;
  • CP系统:在一些分布式数据库系统中,一致性和分区容错性被认为是首要考虑的,而可用性可能会受到一些限制。系统将优先保持数据的一致性和容错性,但可能会在网络分区时牺牲一部分可用性。典型代表如Google的分布式存储系统Bigtable,以及基于Bigtable的开源实现HBase;
  • AP系统:许多大规模互联网应用程序更倾向于追求可用性和分区容错性,而在一致性方面可能做出一些妥协。这些系统通常通过在不同节点之间进行数据复制来提高可用性,并允许在某些情况下返回部分陈旧的数据。典型代表如Amazon的分布式键值存储系统Dynamo;
四、关于CAP理论的思考

CAP理论是分布式系统设计中的一个重要指导原则,但它也存在一些缺陷和局限性。

  • CAP理论将分布式系统的属性简化为三个二进制选择:一致性、可用性和分区容错性。实际上,分布式系统的属性是连续的,并且可以在不同的条件下进行灵活权衡。因此,CAP理论的二分法在某些情况下可能过于简化了问题,无法涵盖所有实际场景;
  • CAP理论没有考虑网络延迟对系统行为的影响。在现实中,网络通信是分布式系统中的主要瓶颈之一,而且网络延迟是不可忽视的。CAP理论假设在有限的时间内完成通信和处理,但实际情况可能因为网络延迟而导致无法在有限时间内完成;
  • CAP理论指出分布式系统不可能同时满足三个属性。然而,对于某些特殊情况和特定的系统设计,实际上可能会近乎同时满足这三个属性。因此,CAP理论在一定程度上可以被绕过或钻空子,不是一个严格的定理;
针对上述论述,我们可以找到一些典型代表作为参考

  • Apache Cassandra:Cassandra是一个分布式、去中心化的NoSQL数据库系统。它在一致性、可用性和分区容错性之间采用了灵活的权衡策略。用户可以根据应用需求配置Cassandra的一致性级别,以获得最合适的系统行为。
  • Apache Kafka:Kafka是一个高吞吐量的分布式发布-订阅消息传递系统。它更加注重可用性和分区容错性,而对于一致性有一些灵活性。Kafka使用分区复制机制来实现容错性,并允许用户根据需求设置消息传递的一致性级别。
所以,系统的CAP属性不是静态不变的,而是可以根据系统配置和设计进行调整。很多系统提供了一致性级别的配置选项,允许用户根据实际需求在一致性和可用性之间进行权衡。
五、总结

CAP理论为我们在设计和选择分布式系统时提供了一个重要的指导原则。我们需要根据系统的需求、数据的重要性以及对一致性和可用性的需求程度,来选择最适合的系统模型。权衡这三个属性,理解系统的妥协是设计可靠、高效分布式系统的关键。在实际应用中,可能需要综合运用不同的技术手段和策略,来达到最优的系统设计。
另外,我们也要考虑到CAP理论存在一些缺陷,开发人员和系统设计者在设计分布式系统时考虑CAP理论的同时,还需要综合考虑其他因素,并结合具体场景和需求来做出最优的系统设计决策。

本篇文章转载自天翼云官方网站开发者社区,了解更多云计算知识可登录天翼云官方网站开发者社区,点击专栏查看更多技术干货,与技术大咖促膝论道!


往期回顾:MongoDB之SCRAM认证- 知乎 (zhihu.com)
回复 支持 反对

使用道具 举报

发表于 2024-11-4 20:21 | 显示全部楼层
假设现在有一个单节点对外提供服务,为了避免其因硬件原因或软件错误发生的异常导致用户不能正常访问,有一个很显然的解决方法是提供多个副本节点。假设有三个副本节点,我们规定两种写入方式:
1、向三个副本写入,只要有一个副本返回写入成功即认为成功,在这种情况下如果出现网络分区就会导致数据不一致此时如果有其他客户端读取 s1 那么就会得到错误的数据,但因为可以正常返回写入成功,此时系统依然是可用的。




2、向三个副本写入,三个副本都返回写入成功才认为成功,但如果出现网络分区后无法全部写入成功,最终会返回报错此时系统是不可用的,但数据并没有出现不一致。




可以发现如果没有网络分区那么系统是可以正常运转,每个系统的数据一致且不会出现系统不可用的情况。但是如果发生了网络分区则情况就不一样了,由此可以引出 CAP 理论:

  • 一致性(Consistency):它要求多节点组成的分布式系统能像单节点一样运作,这意味着所有节点的数据都必须是一致的。
  • 可用性(Availability):每次请求都能获取到非错的响应,非错的响应并不指数据的对错。比如每次读都一定都能得到一个数据,但是这个数据可能是一个过期的数据。
  • 分区容忍性(Partition Tolerance):分区容忍性是指分布式系统在遇到网络分区(节点之间无法通信)此时应该选择 A 还是 C 的问题。
在上面的例子中我们不同的写入策略实际上就是在假设 P 发生时选择 C 还是 A,如果选择三个副本才成功就是选择了 C,选择一个副本就是选择了 A。
基于 CAP 的分布式容错方案

Quorum Replication

Quorum系统背后的思想是通过复制构建容错的存储系统,并确保即使有一些副本故障了,读请求还是能看到最近的写请求的数据。
N(副本数),W(写入成功副本数),R(读取成功副本数,这里的关键点在于,W、R、N之间的关联。Quorum系统要求,任意要发送写请求的W个服务器,必须与任意接收读请求的R个服务器有重叠。这意味着,R加上W必须大于N( 至少满足R + W = N + 1 ),这样任意W个服务器至少与任意R个服务器有一个重合,这样可以保证永远都有一个副本是最新且正确的。在分布式系统中,选择合适的复制策略取决于系统的设计目标和业务需求。以下是两种不同的Quorum Replication组合:

  • N=3,W=1,R=3:这种配置意味着对于写操作,只需要一个副本确认即可认为写操作成功(AP 可用性优先),而对于读操作,则需要从所有三个副本中读取数据才能返回结果(CP 一致性优先)。这种组合适用于读操作比写操作更重要,或者读操作需要最新数据的场景。例如,在一个实时数据仪表板应用中,用户需要看到最新的数据变化,而写入操作(如数据更新)可以容忍短暂的延迟。在这种情况下,读操作的优先级高于写操作,因此R设置为N,确保所有副本都能参与到读操作中,而写操作则可以快速完成,即使只有一个副本确认。
  • N=3,W=3,R=1:这种配置意味着对于写操作,需要所有三个副本都确认才算成功(CP一致性优先),而对于读操作,只需要从任何一个副本读取数据即可(AP可用性优先)。适用场景:这种组合适用于写操作非常重要,必须确保数据的一致性,而读操作可以容忍读取到稍微过时的数据的场景。例如,在一个金融交易系统中,交易的准确性和一致性至关重要,因此写操作(如交易记录的更新)需要所有副本的确认。而读操作,如查看账户余额,可以容忍稍微滞后的数据,因为用户更关心的是交易的最终结果,而不是实时数据。
共识算法

共识算法在实现机制上属于复制状态机(Replicated State Machine)的范畴,复制状态机是一种很有效的容错技术,基于复制日志来实现,每个 Server 存储着一份包含命令序列的日志文件,状态机会按顺序执行这些命令。因为日志中的命令和顺序都相同,因此所有节点会得到相同的数据。因此保证系统一致性就简化为保证操作日志的一致。




分布式 kv 存储 Etcd 采用了Raft共识算法,可以保证在部分节点发生故障的情况下(发生网络分区)也能保证系统的一致性和可用性。Etcd 中规定写入数据只能通过 Leader ,所以数据在 Leader 节点进行全局排序然后复制到其他 follower 节点,这种机制可以满足线性一致性写。Etcd 通过限制只能从 Leader 读以及 Read Index 机制来保证线性一致性读。
所以只有当 Leader 节点产生了网络分区此时整个系统才会产生短暂的不可用,等待选举一个新的 leader 后又可以提供服务,所以基于共识算法的分布式系统本质上是一个 CP+HA (HighAvailable)的系统。
基于共识算法的 分布式数据库 Spanner 就是一个 CP + HA 系统,官方文档说的可用性是优于 5 个 9 ,稍微小于 6 个 9,也就是说,Spanner 在系统出现了大的故障的情况下面,能够在很短的时间内恢复对外提供服务,然后鉴于 Google 强大的自建网络,P 很少发生,所以 Spanner 可以算是一个 CA 系统。
回复 支持 反对

使用道具 举报

发表于 2024-11-4 20:21 | 显示全部楼层
CAP定理的发展

1985年Lynch证明了异步通信中不存在任何一致性的分布式算法(FLP Impossibility)。
2000年,Eric Brewer在PODC的研讨会上提出了一个猜想(CAP理论猜想):一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个!
2002年,Lynch与Gilbert证明了Brewer猜想,论文链接(可访问)
什么是CAP定理

在分布式系统中CAP定理是一个基础定理,证明了在分布式系统中不可能同时获得以下三个属性。

  • Consistency,一致性,在分布式系统中一个发生在**写操作**完成后的**读操作**必须返回这个值或者一个更新的写操作值
  • Availability,可用性,系统中非故障节点接收的每个请求都必须产生响应。
  • Partition tolerance,分区容错,一个节点发送给另一个节点的消息,由于网络原因允许丢失任意多的消息。
以上定义来源于Lynch与Gilbert的论文中给出的定义。
证明

论文采用了反证法的方式:假设存在一种算法A同时满足Consistency、Availability、Partition tolerance。
那么我们来模拟一个反例请求。
假设我们有两个节点组成的集群。

  • 由于算法A满足CAP,根据分区容错性(Partition tolerance)假设两个节点之间的消息都丢失。
  • 客户端向其中一个节点发起了写请求请求完成后,数据从V0→V1;由于节点之间的消息都丢失,所以另一个节点数据还是V0;
  • 客户端向两个节点,都发送了读请求,根据可用性(Availability),两个节点都会对请求产生相应,一个节点响应了数据V1,另一个相应数据V0;
  • 由于一个节点返回了数据V0,这个数据是一个写操作完成之后的数据,违反了一致性的定义(Consistency)。
由此证明了,在分布式系统中,CAP不可能同时满足。


取舍

既然在分布式系统中,不能同时满足CAP,那么设计人员就要根据实际需求进行取舍,我们来看下常见的模型。
CP 模型
牺牲一定的可用性,保证一致性和分区容错性。一个简单的中心式算法能够满足CP要求,一个中心节点维护了数据,其他节点接收到客户端的请求后,自动把请求重定向到中心节点,从中心节点获取到ack后,再把数据响应给客户端。
如果系统需要保证强一致性,可以选择CP模型来进行实现。




CA模型
不存在分区容错,也就是没有网络丢失的可能。单体应用中不会因为节点间的数据通信导致消息丢失。在分布式系统中,由于存在节点间网络交互,所以分区容错性是 必须要考虑的点,可以不考虑CA模型。
AP模型
牺牲系统的强一致性,保证可用性和分区容错性。没有了一致性的束缚,系统中的节点可以将初始值V0响应给每个请求,从而满足可用性的要求。当然实际使用 中系统还是能够提供一定的弱一致性保证。比如分布式系统中,节点使用的本地缓存,可以通过设置有效时间,当有效时间过后,重新加载本地缓存保证了一定的一致性。
生活中的例子


我周末去市场,要买包酸菜,回家做酸菜鱼。
我:来到酸菜摊位前,拿起一包酸菜,问:“这酸菜多少钱一包”
老板娘:“7元”;
老板:“6元”
这个小故事中,我们把老板娘和老板,分别看作是分布式系统中的两个节点,按照上面我们介绍的可能模型,这是一个AP模型,牺牲了一定了一致性。



故事继续,当老板说完6元后,只看到老板娘恶狠狠的盯着老板。那么如果老板不想再次出这种问题,应该咋办呢?看下图


老板接收到价格询问后,可以询问老板娘酸菜什么价,然后再回复我。此场景中如果老板娘耳背,迟迟不回复老板信息,那么对整体的可用性造成一定影响,所以这是一种CP的选择。
故事结尾:我买了这包酸菜,给老板扫了7块钱,我觉得我血赚,大家觉得呢。
参考
【1】An Illustrated Proof of the CAP Theorem
【2】https://github.com/psyho/dyplom/blob/master/bibliografia/brewers-conjecture/BrewersConjecture-SigAct.pdf
回复 支持 反对

使用道具 举报

发表于 2024-11-4 20:22 | 显示全部楼层
这篇文章着重点不在于科普,毕竟关于CAP理论的文章,网上很多。所以本文科普篇幅尽量小(只包含概念描述)
本文通过以下几个问题,从侧面描述。文中个人观点较多,看官理性对待。

  • 为什么CAP三者不可兼得?
  • 实践中,怎么应用CAP?
  • 不考虑一致性的系统,有什么存在的意义呢?
CAP定理科普

CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。这三个要素最多只能同时实现两点,不可能三者兼顾。

  • 一致性(C):这里是指100%强一致性。在分布式系统中的所有数据备份,在同一时刻整个系统的副本都拥有的一致的数据。
  • 可用性(A):这里是指100%可用性。客户端无论访问到哪个没有宕机的节点上,都能在有限的时间返回结果,并不是指整个系统处于可用状态。
  • 分区容错性(P):网络中允许丢失一个节点发给另一个节点的任意多的消息,即对网络分区的容忍。在发生网络分区时,能继续保持可用性或者一致性。如果一个系统要求在运行过程中不能发生网络分区,那么这个系统就不具备分区容错性。
为什么CAP三者不可兼得?

在分布式系统中,各个组建必然部署在不同的节点上,因此必然出现子网络,同时网络本身又是不可靠的,一定存在延迟和数据丢失,即网络分区是必然存在的。所以P(分区容错性)是分布式系统必须要面对和解决的问题(你无法要求在永远不发生网络分区的环境下运行分布式系统)。
因此CAP三者不可兼得,变成如何在C(一致性)、A(可用性)二者进行抉择,可以举个例子来说明:在分布式环境中,为了确保系统可用性,通常会采用将数据复制到多个备份节点,而复制的过程需要通过网络交互。当发生网络分区时,你将面临两个选择:

  • 如果坚持保持各节点之间的数据一致性(选择C),你需要等待网络分区恢复后,将数据复制完成,才可以向外部提供服务。期间发生网络分区将不能对外提供服务,因为它保证不了数据一致性。
  • 如果选择可用性(选择A),发生网络分区的节点,依然需要向外提供服务。但是由于网络分区,它同步不了最新的数据,所以它返回数据,可能不是最新的(与其他节点不一致的)数据。
这里需要强调一句,CAP三者不可兼得,仅仅是指在发生网络分区情况下,我们才需要在A和C之间进行抉择,选择保证数据一致还是服务可用。而集群正常运行时,A和C是都可以保证的。

  • CP架构在当发生网络分区时,为了保证返回给客户端数据准确性,为了不破坏一致性,可能会因为无法响应最新数据,而拒绝响应。在网络分区恢复后,完成数据同步,才可处理客户端请求。
  • AP架构在发生网络分区时,发生分区的节点不需要等待数据完成同步,便可处理客户端请求,将尽可能的给用户返回相对新的数据。在网络分区恢复后,完成数据同步。
实践中,怎么应用CAP?

CAP描述的一致性和可用性,都是100%的强度。在生产实践中,我们并不需要100%的一致性和可用性,因此我们需要对一致性和可用性之间进行权衡,选择CP架构或者AP架构。
例如,ZooKeeper,在少数成员宕机时,仍可以向客户端提供正确的服务,而当多数派成员宕机时,ZooKeeper则选择了一致性,为了保证给客户端响应正确的数据,ZooKeeper此时则不会继续提供服务。所以我们认为ZooKeeper在关键时刻选择一致性,但是它仍拥有很高的可用性。
2017 年,Google 公司的第一代 Spanner 系统已经诞生。Brewer 写了一篇文章讲述了 Google 公司的 Spanner 系统,并且近一步阐述了按照 CAP 定理 Spanner 是一个什么样特性的系统。在文中,Brewer 指出 Spanner 系统说是”实际上的 CA”(effectively CA)系统。从架构上来讲,Spanner 是一个 CP 系统,也就是说当出现网络分区时,Spanner 选择的是保证数据的一致性,放弃可用性的。但实际上,Spanner 是具有非常高可用性效果的一个系统,从架构上 Spanner 没有达到 CAP 定理要求的那种完全可用性,但是也达到非常高的可用性,由于采用多副本的设计,个别副本出现网络分区,并不影响用户能感知到的可用性。按 CAP 定理的定义,当这些个别副本出现网络分区时,这些节点是不可用的,也就是系统没有达到完全可用性。但是此时的用户请求是可以被其他副本服务的,此时服务是可用的,也就是说用户仍然感知到 Spanner 是可用的。所以说用户感知的可用性和 CAP 定理中的可用性不是一个概念。我们追求的应该是用户感知的可用性。
不考虑一致性的系统,有什么存在的意义呢?

这里以eureka为例,eureka各节点互相独立、平等的,各节点都提供查询和注册服务(读、写请求)。当发生网络分区,eureka各节点依旧可以接收和注册服务。并且当丢失过多客户端时,节点会进入自我保护(接收新服务注册、不删除过期服务)。在该种模式下,eureka集群剩下最后一个节点,也可以向外提供服务。尽管向外提供的数据可能是过期的数据。
考虑选择一致性还是可用性的情况,一定是在发生网络故障、且在关键时间,此时一致性和可用性才是互斥的。而网络故障、且非常关键时间,在一个健壮的系统中,这类情况是非常少的,我们大多数情况都能保证一致性和可用性。
eureka集群正常运行时,各节点之间可以正常通讯、保持心跳、复制数据,以此保持数据的一致性。但发生网络分区时,eureka确实选择了可用性,而放弃了一致性。
回复 支持 反对

使用道具 举报

发表于 2024-11-4 20:22 | 显示全部楼层
1. CAP理论介绍

CAP定理(CAP theorem):对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性(Consistency) (等同于所有节点访问同一份最新的数据副本)
  • 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据)
  • 分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。)​



2. 为什么不能同时满足

对于CAP理论中,分布式系统要保障整体的服务,因此(Partition tolerance)分区容错性必然存在。那么为什么CA不能同时存在?因为分区之间的通信可能通信失败。



① 假设有两个数据分区DB1和DB2,存储着相同的一个数据,都是Version0。 ② 有写请求进来,修改了DB1中的数据到Version1,正常情况下需要将修改同步到DB2,但是由于之间通信故障,DB2数据没能成功修改。 ③ 当有读请求进来,请求DB1,返回正确数据Version1,请求DB2,由于数据没有成功修改,要么牺牲一致性,返回Version0,要么牺牲可用性,等故障恢复后再返回数据,阻塞掉请求。 ​
因此,CAP理论中CA无法同时满足。那么可能存在两种情况:

  • CP without A
  • AP without C
3. 要A还是要C

CP without A: 有些系统中一致性是本质要求,例如Redis分布式存储,ZooKeeper任何时候访问ZK都可以获得一致性的结果。极端情况下可能丢弃一些请求,从而保障一致性。 ​
AP without C: 比如有的网页对一致性要求不是那么高,对商品价格进行更改,但是要保障用户仍然能顺利的访问网页。但是会在付款的时候对价格进行再次验证。
<hr/>
Ref:
1. 《CAP 定理的含义》阮一峰
2. 《CAP定理》维基百科
回复 支持 反对

使用道具 举报

发表回复

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

本版积分规则

关闭

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

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