概述
在分布式系统架构下,CAP理论已经成为公认的定理,随着二十年技术的发展,CAP理论的解读也发生了些变化。本文简要介绍CAP理论的原理及证明思路,以及在分布式架构下的适用性,以加深理解。
1、CAP简介
CAP理论是计算机科学家Eric Brewer在2000年提出的理论猜想,在2002年被证明并成为分布式计算领域公认的定理,其理论的基本观念是,在分布式系统中不可能同时满足以下三个特性:
- C:consistency一致性
- A:Availability可用性
- P:Partition Tolerance分区容错性
在"CAP Twelve Years Later: How the “Rules” Have Changed"一文中给CAP做了简单的定义:
The CAP theorem states that any networked shared-data system can have at most two of three desirable properties:consistency © equivalent to having a single up-to-date copy of the data; high availability (A) of that data (for updates); and tolerance to network partitions §
1.1 Consistency一致性
CAP理论中的一致性指的是Serializability可线性化的意思,也就是非常特殊的强一致性,但是这里的Consistency和ACID中的一致性是两回事,事务中的一致性包含了对状态的后续处理而CAP定理并不涉及到状态的后续处理。因此CAP中的一致性指"all nodes see the same data at the same time",即更新操作成功后,所有节点在同一时间的数据完全一致。对于一致性的理解,可以从客户端和服务端两个不同的视角来分析。
- 从客户端来看,一致性主要指的是多并发请求时更新过的数据如何获取的问题。如果更新过的数据需要立刻被后续的请求获取到就是强一致性,如果能容忍后续的请求部分或者全部访问不到则是弱一致性,如果经过一段时间后要求能访问到更新后的数据则是最终一致性。
- 从服务端来看,一致性则是数据更新后如何同步到整个分布式系统,以保证数据最终一致性。
一致性一般在并发读写的时候才出现这个问题,需要结合并发读写的场景考虑
- 如上左图所示,客户端向节点N1更新数据V0->V1,在接下来读操作过程中,从N1节点读取的是V1,N2节点读取的是V0,对于单节点没有问题,但是在分布式系统中N1节点和N2节点读取的结果就不一致了
- 如上右图所示,客户端在向N1发起写操作时,N1节点向N2节点发起了同步操作,将两个节点的值都修改为V1,这时客户端从N1和N2节点获取到的值都是V1,保证了一致性
上述例子用可线性化解释就是:
如果 B 操作在成功完成 A 操作之后,那么整个系统对 B 操作来说必须表现为 A 操作已经完成了或者更新的状态。
如果系统内部发生了故障从而导致系统的节点无法发生一致性变化,比如N2节点无法同步N1节点的数据。这也意味着客户端查询最新数据的时候,部分节点很可能会看到旧数据,或者说获取到不同版本的数据。此时,为了保证分布式系统对外的数据一致性,于是选择不返回任何数据。
1.2 Availability可用性
可用性指"reads and writes always succeed",即要求系统内的节点们接收到了无论是写请求还是读请求,都要能处理并给回响应结果。同时有几点必须满足的条件:
- 返回结果必须在合理的时间以内,这个合理的时间是根据业务来定的,如果超过业务规定的返回时间这个系统也就不满足可用性;
- 系统能所有能正常接收请求的节点都能返回结果,如果节点宕机了不能正常接收请求但是其它节点可以正常返回,可以说系统依然是可用的,不影响可用性指标。如果所有节点都能返回,但是返回的数据不一致,其中一个节点是1天前的数据,另一个是1s前的,也称为系统可用的。
一般在描述一个系统可用性时,通过停机时间来计算,比如某某系统可用性可以达到5个9,意思就是说该系统的可用水平是99.999%,即全年停机时间不超过(1-0.99999)36524*60 = 5.256min,这是一个极高的要求。
可用性分类 | 可用水平(%) | 年可容忍停机时间 |
---|---|---|
容错可用性 | 99.9999 | <1 min |
极高可用性 | 99.999 | <5 min |
具有故障自动恢复能力的可用性 | 99.99 | <53 min |
高可用性 | 99.9 | <8.8h |
1.3 Partition tolerance分区容错性
分布式系统架构下会有多个节点,这些节点之间通过网络进行通信,但是当网络故障或其它原因节点之间通信出现异常,当前的分布式系统就出现了分区。分区容错性指"the system continues to operate despite arbitrary message loss or failure of part of the system",即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。
2、CAP理论证明
CAP的证明是基于异步网络的,假设两个节点集{DC1, DC2},由于网络异常导致DC1和DC2之间所有的通讯都断开了,如果在DC1中写,在DC2中读刚写的数据,DC2中返回的值不可能是DC1中的更新值。由于A的要求,DC2一定要返回这次读请求,由于P的存在,导致C一定是不可满足的。
1)分布式系统中正常运行流程
下图展示了分布式系统正常运转的流程,用户向N1节点请求数据更新,程序A更新数据库V0->V1,分布式系统将数据进行同步操作,将V1更新同步到N2节点,使得N2中的数据V0也更新为V1,N2中的数据再响应N2的请求。
- 在满足一致性的时候,N1和N2中的数据是一样的,V0=V0。
- 在满足可用性的时候,用户不管是请求N1或者N2,都会得到立即响应。
- 在满足分区容错性的情况下,N1和N2有任何一方宕机,或者网络不通的时候,都不会影响N1和N2彼此之间的正常运作
2)网络分区出现故障场景
假设在N1和N2之间网络出现通信故障,有用户向N1发送数据更新请求,N1中的数据V0将被更新为V1,由于网络异常数据更新没有同步到N2,所以N2中的数据依旧是V0。这个时候,有用户向N2发送数据读取请求,由于数据还没有进行同步,应用程序没办法立即给用户返回最新的数据V1。
- 牺牲数据一致性,保证可用性,将旧的数据V0返回给用户。
- 牺牲可用性,保证数据一致性。阻塞等待,直到网络连接恢复,数据更新操作sync完成之后,再给用户响应最新的数据V1。
上述过程证明了要满足分区容错性的分布式系统,只能在一致性和可用性两者中,选择其中一个。
3、CAP之间权衡
根据CAP理论,在分布式系统中无法同时满足一致性、可用性和分区容错性,在实际应用中又如何来进行取舍。
3.1 CA模型
舍弃分区容错性意味着将所有的服务器搬到一个网络节点内,显然不满足分布式系统的可伸缩性扩展要求。因此在分布式系统中P是一个基本要求,不选 P,一旦发生分区错误,整个分布式系统就完全无法使用了,这是不符合实际需要的。所以,对于分布式系统,我们只能能考虑当发生分区错误时,如何选择一致性和可用性。CA模型常见的例子包括单站点数据库、集群数据库、LDAP和XFS文件系统等,通常是通过两阶段提交和缓存验证协议实现的。
3.2 CP模型
舍弃A保证Consistency,不同节点之间需要保证数据的一致性,但是因为网络分区的不稳定,可能出现其它节点的数据没有及时更新。如果一个分布式系统不要求强的可用性,即允许系统停机或者长时间无响应的话,就可以在CAP三者中保障CP而舍弃A。这样的分布式系统一旦发生网络故障或者消息丢失等情况,就要牺牲用户体验,等数据一致后再让用户访问系统。CP模型下典型的场景是分布式数据库,通过悲观锁机制或少数分区不可用来优先保证数据一致性。像分布式缓存Redis、分布式协调中心Zookeeper,满足分布式系统下的数据一致性是最基本的要求。
3.3 AP模型
AP模型是在保证高可用和分区容错性的同时,舍弃数据一致性。为了保证高可用性,分布式系统下的不同节点需要立即返回结果给客户端,这样可能会出现不同节点之间的数据不一致,也就是会出现全局数据的不一致。也可以说是舍弃了数据的强一致性,保证的是数据的最终一致性(BASE理论)。AP模型使用的场景非常多,在一些高并发的系统中利用排队和乐观锁机制优先保证系统的可用性,避免造成系统的阻塞。
4、CAP理论的理解
CAP理论的三种特性不是Boolean类型,而是范围类型。比如对于可用性,与业务的时延要求有关,当业务的时延要求降低后,又能达到可用性要求。对于分区容错性,在Raft多数派选举机制下,当多数节点出现问题后才会投票确认分区出现故障。
4.1 CAP三选二的误导性
CAP理论中三个特性只能满足二个其实又一定的误导性。首先,在系统不存在分区P的情况下就没什么理由牺牲C和A。其次,C与A之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,甚至因为特定的数据或用户需求而有所不同。最后,这三种性质都可以在程度上衡量,并不是非黑即白的有或无。可用性显然是在0%到100%之间连续变化的,一致性分很多级别(强一致性、弱一致性和最终一致性),连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。
4.2 CAP理论下多副本分布式数据库
在大规模的分布式系统里,会把海量的数据进行切分存储到不同的节点上,同时保证高可用也需要对这些节点配置副本备份。
- 当分布式系统中只有分片没有备份节点的时候,同样需要遵守CAP理论,不过是在跨分片的事务中才存在。比如三个节点N1、N2和N3分别存放了A表、B表和C表的数据,当有一个事务需要在N1/N2/N3上同时执行语句,等到所有节点返回成功后才会返回成功。但是当N3节点出现故障,发生了分区以后,根据CAP理论,要么直接返回部分成功的结果给客户端,要么直接等待客户端超时或者返回失败给客户端。当返回部分成功的时候,这就是选择了可用性(A),当等待超时或者返回失败给客户端的时候,就是选择了一致性(C)。
- 当分布式系统中多个节点是主备关系的时候,每个节点存储了一套完整的数据。当事务在一个节点上成功,其它节点出现网络故障时,也可以选择是事务回退或写成功。如果是事务回退,对外的选择就是事务一致性;如果认为选择成功,则认为选择了可用性。
在分布式数据库系统中,分区容忍性是必须的,分区是始终会存在的,因此需要在一致性和可用性之间进行权衡。
- CP without A:分布式系统容许系统停机或者长时间无响应,一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。传统的分布式数据库事务都属于这种模式,对于金融行业的分布式数据库产品而言,优先保证数据的一致性。
- AP without C:分布式系统中允许数据不一致,一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。
在实际的分布式数据库系统中,基于分片解决扩展性问题并可以实现负载均衡,当某个分片服务不可用时,只会影响部分业务,即服务降级。同时基于多副本构成集群架构,提升系统的高可用。
假设N表示数据的副本总数、W表示更新数据时需要保证写完成的节点数、R表示读取数据时需要读取的节点数。
- 强一致性:R+W>N,以保证对副本的读写操作会产生交集,从而保证可以读取到最新版本。例如,对于典型的一主一备同步复制的关系型数据库,N=2,W=2,R=1,则不管读的是主库还是备库的数据,都是一致的
- 弱一致性:R+W<=N,如果读写操作的副本集合不产生交集,就可能会读到脏数据。例如对于一主一备异步复制的关系型数据库,N=2,W=1,R=1,则如果读的是备库,就可能无法读取主库已经更新过的数据,所以是弱一致性
- 对于分布式系统,为了保证高可用性,一般设置N>=3。
不同的N,W,R组合,是在可用性和一致性之间取一个平衡,以适应不同的应用场景。
- 如果N=W,R=1,任何一个写节点失效,都会导致写失败,因此可用性会降低,但是由于数据分布的N个节点是同步写入的,因此可以保证强一致性。
- 如果N=R,W=1,只需要一个节点写入成功即可,写性能和可用性都比较高。但是读取其他节点的进程可能不能获取更新后的数据,因此是弱一致性。这种情况下,如果W<(N+1)/2,并且写入的节点不重叠的话,则会存在写冲突。
4.3 CAP的不足
根据专家的分析,CAP并不是一个严谨的定律,并不是牺牲了Consistency,就一定能同时获得Availability和Partition Tolerance。CAP定理有以下不足:
- CAP 定理本身是没有考虑网络延迟的问题的,它认为一致性是立即生效的,但是,要保持一致性,是需要时间成本的,这就导致往往分布式系统多选择AP方式
- 由于时代的演变,CAP定理在针对所有分布式系统的时候,出现了一些力不从心的情况,导致很多时候它自己会把以前很严谨的数学定义改成了比较松弛的业务定义,类似于我们看到,CAP定理把一致性、可用性、分区容错都变成了一个范围属性,而这和CAP定理本身这种数学定理般的称呼是有冲突的,出现了不符合数学严谨定义的问题。
- 在实践中以及后来CAP定理的提出者也承认,一致性和可用性并不仅仅是二选一的问题,只是一些重要性的区别,当强调一致性的时候,并不表示可用性是完全不可用的状态。比如,Zookeeper只是在master出现问题的时候,才可能出现几十秒的不可用状态,而别的时候,都会以各种方式保证系统的可用性。而强调可用性的时候,也往往会采用一些技术手段,去保证数据最终是一致的。CAP定理并没有给出这些情况的具体描述。
- CAP理论从工程角度来看只是一种状态的描述,它告诉大家当有错的时候,分布式系统可能处在什么状态。但是,状态是可能变化的。状态间如何转换,如何修补,如何恢复是没有提供方向的。
5、BASE理论
在分布式系统中,面对CAP权衡时,通常的做法会选择AP舍弃C(舍弃强一致性但保证最终一致性),这其实也是分布式领域的另外一个理论,叫BASE理论。BASE是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)。BASE理论是对CAP理论的延伸,其核心思想是:
即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)
5.1 基本可用(Basically Available)
基本可用是指分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
- 响应时间上的损失:正常情况下的客户端请求0.5s即返回给用户结果,而基本可用的情况下可以在1秒甚至2s返回结果,超过一定阈值用户就接受不了
- 功能上的损失:在一个购物网站上,正常情况下,用户可以顺利完成每一笔订单,但是到了促销活动期间,为了保障购物系统的稳定性,部分消费者可能会被引导到一个服务降级页面。
5.2 软状态(Soft State)
软状态是相对原子性来说的
- 原子性(硬状态):要求多个节点的数据副本都是一致的,这是一种"硬状态"
- 软状态(弱状态):允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延迟
比如在分布式数据库MySQL的复制中一般一份数据会有多个副本,允许不同节点间副本同步的延时就是软状态的体现。
5.3 最终一致性(Eventual Consistency)
系统不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性,从而达到数据的最终一致性。这个时间期限取决于网络延时,系统负载,数据复制方案设计等等因素。最终一致性是弱一致性的特定形式,官方的定义是:
系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。
最终一致性模型有5种变种:
- 因果一致性(Causal consistency):如果节点A在更新完某个数据后通知了节点B,那么节点B的访问修改操作都是基于A更新后的值,同时和节点A没有因果关系的C的数据访问则没有这样的限制
- 读己之所写(Read your writes):因果一致性的特定形式,一个节点A总可以读到自己更新的数据
- 会话一致性(Session consistency):访问存储系统同一个有效的会话,系统应保证该进程读己之所写
- 单调读一致性(Monotonic read consistency):一个节点从系统中读取一个特定值之后,那么该节点从系统中不会读取到该值以前的任何值
- 单调写一致性(Monotonic write consistency):一个系统要能够保证来自同一个节点的写操作被顺序执行(保证写操作串行化)
参考资料:
- 《分布式系统常用技术及案例分析》
- https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/
- 分布式系统CAP理论初探,阿飞算法
- 分布式系统的CAP定理详解,码道仕
- 分布式系统之CAP理论,我们对它的理解和误解
- 这可能是我看过最通俗也是最深刻的CAP理论,51CTO技术栈
- 分布式系统之CAP理论,架构师
- https://www.cnblogs.com/stateis0/p/9062123.html
- https://segmentfault.com/a/1190000018019595
转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/124442443
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!
最后
以上就是专注小蝴蝶为你收集整理的分布式系统CAP理论解析的全部内容,希望文章能够帮你解决分布式系统CAP理论解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复