术→技巧, 研发

分布式理论CAP与BASE

钱魏Way · · 0 次浏览

CAP理论

CAP简介

CAP理论是计算机分布式系统设计中的一个重要理论,由Eric Brewer教授在2000年的ACM会议上首次提出。CAP是Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容忍性)的首字母缩写。

  • 一致性(Consistency):在分布式系统中,一致性是指数据在多个副本之间能够保持一致的性质。对于系统的任何一次读操作都必须返回最新写入的数据。
  • 可用性(Availability):每次请求都能获取到(非错误)响应——但是并不保证返回的数据是最新的。
  • 分区容忍性(Partition tolerance):系统即使在网络分区或信息传递延迟的情况下,也能够继续运行并满足系统设计的初衷。

CAP理论的核心观点是,在一个分布式系统中,一致性、可用性和分区容忍性这三个特性无法同时满足,最多只能满足其中的两项。这个理论对分布式系统设计有着深远的影响。

Consistency 一致性

在CAP理论中,一致性是指“所有节点在同一时刻看到的数据是一致的”。换句话说,如果系统中的某个节点更新了数据,那么其他所有的节点都应该立刻看到这个更新,这就是所谓的强一致性。

然而,实际上在分布式系统中,由于网络延迟、节点故障等因素,很难做到真正的强一致性。在这种情况下,常常需要使用一些更弱的一致性模型。比如:

  • 最终一致性(Eventual Consistency):系统保证在没有新的更新操作后,经过一段时间,所有的数据副本最终都会达到一致的状态。这种模型允许系统在短时间内出现数据不一致的情况。
  • 因果一致性(Causal Consistency):如果操作A在时间上先于操作B,并且操作B可能看到操作A的结果,那么操作A就对操作B有因果影响。因果一致性就是要求如果一个操作A在因果上先于操作B,那么在所有的节点上,操作A的更新都应该在操作B之前看到。
  • 序列一致性(Sequential Consistency):如果所有的操作在所有的节点上看到的顺序是一致的,那么就说系统满足序列一致性。注意这里的顺序是指所有操作的逻辑顺序,而不是实际的物理时间顺序。

总的来说,一致性问题是分布式系统中非常复杂的问题,需要根据系统的实际需求和条件来选择合适的一致性模型。

对于一致性,可以分为从客户端和服务端两个不同的视角。

  • 客户端:从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。
  • 服务端:从服务端来看,则是更新如何分布到整个系统,以保证数据最终一致。

对于一致性,可以分为强/弱/最终一致性三类。从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。

  • 强一致性:对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。
  • 弱一致性:如果能容忍后续的部分或者全部访问不到,则是弱一致性。
  • 最终一致性:如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。

Availability 可用性

在CAP理论中,可用性(Availability)是指对于系统的任何请求,系统都需要在有限的时间内返回一个合理的响应。

这里的“合理的响应”并不一定指的是最新或者最准确的数据。例如,如果系统正在进行数据备份或者数据迁移,此时可能无法访问到最新的数据,但是系统仍然可以返回目前可用的、可能稍旧一些的数据,这种情况下,我们仍然认为系统是可用的。

在分布式系统中,可用性是一个非常重要的指标,因为对于用户来说,一个无法访问的系统和一个不存在的系统没有任何区别。因此,分布式系统通常需要通过各种手段来提高可用性,例如数据冗余、负载均衡、故障转移、自动恢复等。

然而,可用性和一致性往往是互相冲突的。例如,为了提高可用性,系统可能需要返回旧的数据,但这就可能导致一致性的问题。这就是CAP理论所说的,无法同时满足一致性、可用性和分区容忍性。在实际设计中,需要根据系统的具体需求来权衡这三者。

对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。所以,一般我们在衡量一个系统的可用性的时候,都是通过停机时间来计算的。

可用性分类 可用水平(%) 年可容忍停机时间
容错可用性 99.9999 <1 min
极高可用性 99.999 <5 min
具有故障自动恢复能力的可用性 99.99 <53 min
高可用性 99.9 <8.8h
商品可用性 99 <43.8 min

通常我们描述一个系统的可用性时,我们说淘宝的系统可用性可以达到5个9,意思就是说他的可用水平是99.999%,即全年停机时间不超过 (1-0.99999)*365*24*60 = 5.256 min,这是一个极高的要求。

好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。一个分布式系统,上下游设计很多系统如负载均衡、WEB服务器、应用代码、数据库服务器等,任何一个节点的不稳定都可以影响可用性。

Partition Tolerance分区容错性

在CAP理论中,分区容忍性(Partition Tolerance)是指,在网络分区(Partition)情况下系统能够继续运行。网络分区是指在网络通信中,由于某种原因(如网络硬件故障、路由故障等),使得网络中的一部分节点无法与其余部分节点通信,从而导致网络被分割成两个或多个孤立的部分。

分布式系统中的节点通常通过网络进行通信,如果某些节点之间的网络连接出现问题,那么就可能发生网络分区。在这种情况下,如果系统仍然能够提供服务,并且满足一致性和可用性的要求,那么就说系统有分区容忍性。

然而,由于网络问题往往是无法预料和避免的,所以在分布式系统设计中,通常认为分区容忍性是必须要满足的。也就是说,真正的问题通常是如何在满足分区容忍性的前提下,去权衡一致性和可用性。

在面对网络分区时,一种处理方式是牺牲一致性,允许系统在不同的分区中有不同的数据版本,这样可以保证系统的可用性。另一种处理方式是牺牲可用性,即在网络分区发生时,停止服务,以此来保证一致性。这两种方式各有优缺点,需要根据系统的具体需求来选择。

三者不可得兼

CAP理论的主张是,在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容忍性(Partition tolerance)这三个特性无法同时满足,最多只能满足其中的两项。

这个理论主要基于网络分区是无法避免的现实情况。在一个大型的分布式系统中,由于网络故障、硬件故障等因素,总会存在一些节点无法和其他节点通信的情况,这就发生了网络分区。

当网络分区发生后:

  • 如果我们希望保持一致性(C)和可用性(A),那就意味着系统必须忽视分区(P)的存在,然而这是不可能的,因为网络分区可能意味着数据无法复制到所有的节点,从而无法保证全局一致性。
  • 如果我们希望保持一致性(C)和分区容忍性(P),那就必须牺牲可用性(A),因为当网络分区发生后,为了保持一致性,系统必须停止写入操作,直到网络分区问题解决。
  • 如果我们希望保持可用性(A)和分区容忍性(P),那就必须牺牲一致性(C),因为在网络分区发生后,为了保持系统的可用性,可能需要允许数据在不同的分区中有不同的版本,从而无法保证全局一致性。

因此,CAP理论的真实含义是,当网络分区发生时,我们必须在一致性和可用性之间进行权衡。这就是为什么三者不能同时得到的原因。

CAP原则权衡

通过CAP理论,我们知道无法同时满足一致性、可用性和分区容错性这三个特性,那要舍弃哪个呢?

  • CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但是对于分布式系统,分区是客观存在的,其实分布式系统理论上是不可选CA的。
  • CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
  • AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。

对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。

对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁可停止服务,这是保证CA,舍弃P。貌似这几年国内银行业发生了不下10起事故,但影响面不大,报道也不多,广大群众知道的少。还有一种是保证CP,舍弃A。例如网络故障事只读不写。

CAP原则实际应用

我们应该都接触过微服务,常见的可以作为注册中心的组件有:ZooKeeper、Eureka、Nacos…。

  • ZooKeeper 保证的是 CP。任何时刻对 ZooKeeper 的读请求都能得到一致性的结果,但是, ZooKeeper 不保证每次请求的可用性比如在 Leader 选举过程中或者半数以上的机器不可用的时候服务就是不可用的。
  • Eureka 保证的则是 AP。Eureka 在设计的时候就是优先保证 A (可用性)。在 Eureka 中不存在什么 Leader 节点,每个节点都是一样的、平等的。因此 Eureka 不会像 ZooKeeper 那样出现选举过程中或者半数以上的机器不可用的时候服务就是不可用的情况。 Eureka 保证即使大部分节点挂掉也不会影响正常提供服务,只要有一个节点是可用的就行了。只不过这个节点上的数据可能并不是最新的。
  • Nacos 不仅支持 CP 也支持 AP。

BASE理论

BASE简介

BASE理论是对大规模分布式系统的特性的一个描述,它起源于对传统ACID事务特性的批评和重新定义。BASE是Basically Available(基本可用)、Soft state(软状态)、Eventually consistent(最终一致性)的缩写。

  • Basically Available(基本可用):这个特性表示系统可能会因为分布式的部署方式,出现小段时间内的不可用状态,但是不会影响整个系统的绝大部分,即基本可用。例如,某些数据可能由于网络的问题暂时访问不了,但使用冗余数据可以保证系统整体的可用性。
  • Soft state(软状态):即系统的状态可以有一段时间的不一致,或者说系统可以处于中间状态,并不影响系统整体的可用性。例如,在网络分区的情况下,各个分区可以保持独立的状态,而不需要与其他分区保持一致。
  • Eventually consistent(最终一致性):这是指系统必须在没有输入的情况下,最终达到一致的状态。然而,系统在达到一致性之前,允许存在短暂的一致性窗口。例如,电子邮件系统就是一个最终一致性的系统,我们发送邮件后,可能需要一段时间邮件才能到达收件人,但只要不再有新的输入,最终所有的收件人都会收到这个邮件。

BASE理论是对CAP中一致性和可用性权衡的结果,其目标是为了满足大规模互联网系统的需求,提供更强的可用性。

BASE核心思想

即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。也就是牺牲数据的一致性来满足系统的高可用性,系统中一部分数据不可用或者不一致时,仍需要保持系统整体“主要可用”。

BASE 理论本质上是对 CAP 的延伸和补充,更具体地说,是对 CAP 中 AP 方案的一个补充。

为什么这样说呢?CAP 理论这节我们也说过了:如果系统没有发生“分区”的话,节点间的网络连接通信正常的话,也就不存在 P 了。这个时候,我们就可以同时保证 C 和 A 了。因此,如果系统发生“分区”,我们要考虑选择 CP 还是 AP。如果系统没有发生“分区”的话,我们要思考如何保证 CA 。

因此,AP 方案只是在系统发生分区的时候放弃一致性,而不是永远放弃一致性。在分区故障恢复后,系统应该达到最终一致性。这一点其实就是 BASE 理论延伸的地方。

BASE理论三要素

基本可用

“基本可用”是BASE理论中的一个概念,这个理论是用来描述大规模分布式系统特性的。”Basically Available(基本可用)”表示的是,即使在面临部分故障的情况下,系统也应该保持在线并能够提供服务。

“基本可用”并不等同于100%的可用,而是指即使在系统部分组件失效或者网络出现问题的情况下,整个系统仍然能够维持基础的功能运行,尽力为用户提供所需服务。可能部分数据无法访问,或者响应速度有所下降,但总体上,系统仍然能够对外提供服务。例如,在电商网站中,即使商品推荐系统出现问题,用户仍然可以浏览商品、添加购物车和完成购买等基本功能,这就是”基本可用”的体现。

这种设计理念是为了在面临故障时,最大化地提供服务,减少用户的不便,提升系统的健壮性和可用性。

软状态

“软状态”(Soft state)是BASE理论中的一个概念,这是一种可以容忍一段时间内的系统状态不一致的策略。在分布式系统中,由于多个节点之间的通信延迟或者网络故障等因素,可能会出现某个或某些节点的状态与其他节点的状态不同步的情况,即产生“软状态”。

在这种模式下,系统不需要随时保证所有节点的数据完全一致,而是允许在一段时间内,系统处于这种不一致的状态,然后通过后续的数据同步、更新等操作,使其最终达到一致。

例如,在一个社交网络应用中,当一个用户改变了他的头像,这个头像的改变可能不会立即在所有服务器上更新,可能有些服务器上的用户看到的还是旧的头像,但是经过一段时间,所有服务器上的数据会逐渐同步更新,最终达到一致,这就是“软状态”。

“软状态”的设计理念是为了在分布式环境下提高系统的性能和可用性,接受短暂的数据不一致,以获取更好的系统性能和更高的可用性。

最终一致性

最终一致性(Eventually consistent)是分布式计算中的一种一致性模型。在最终一致性模型中,系统不保证在任何给定的时间点,所有节点的数据都是一致的。然而,它保证在没有新的数据更新进来的情况下,经过一段时间,所有的复制节点最终会达成数据一致。

简单来说,最终一致性就是允许系统在一段时间里处于不一致的状态,但最终所有节点会达到一致的状态。这是一种比较宽松的一致性模型,适用于对数据一致性要求不是非常严格,但需要高可用性和可扩展性的场景。

比如,在社交网络中,用户发表了一条新的动态,这条动态可能需要一段时间才能在所有的好友的动态流中显示出来,这就是最终一致性的表现。

最终一致性的优点是可以提高系统的可用性和性能,因为系统不需要在每次数据更新时都立即保证所有节点的数据一致性,从而避免了等待数据同步的时间。但缺点是在数据最终达到一致之前,用户可能看到的是旧的或者不一致的数据。

“软状态”(Soft State)和”最终一致性”(Eventual Consistency)都是描述分布式系统中状态变化的概念,但它们关注的方向有所不同。

  • “软状态”指的是系统状态可以因为没有输入而发生变化。在这种情况下,系统的状态不是实时的,可能会有一段时间的延迟。这意味着即使没有任何新的输入,系统的状态也可能会改变,比如由于消息的延迟、丢失或者重复等原因。
  • “最终一致性”是指系统在没有新的数据更新进来的情况下,经过一段时间,所有的复制节点最终会达到一致的状态。这就表明,虽然在某个具体的时间点,系统中的各个节点可能不一致,但是最终,他们会达到一致的状态。

总之,”软状态”是关注系统状态可能会因为没有新的输入而发生变化,而”最终一致性”是关注在没有新的更新的情况下,系统最终会达到一致的状态。这两个概念都是为了在分布式系统中提高可用性和性能,而接受一定的数据一致性降级。

分布式一致性的 3 种级别:

  • 强一致性:系统写入了什么,读出来的就是什么。
  • 弱一致性:不一定可以读取到最新写入的值,也不保证多少时间之后读取到的数据是最新的,只是会尽量保证某个时刻达到数据一致的状态。
  • 最终一致性:弱一致性的升级版,系统会保证在一定时间内达到数据一致的状态。

业界比较推崇是最终一致性级别,但是某些对数据一致要求十分严格的场景比如银行转账还是要保证强一致性。

最终一致性怎么保证呢?

  • 读时修复: 在读取数据时,检测数据的不一致,进行修复。比如 Cassandra 的 Read Repair 实现,具体来说,在向 Cassandra 系统查询数据的时候,如果检测到不同节点 的副本数据不一致,系统就自动修复数据。
  • 写时修复: 在写入数据,检测数据的不一致时,进行修复。比如 Cassandra 的 Hinted Handoff 实现。具体来说,Cassandra 集群的节点之间远程写数据的时候,如果写失败 就将数据缓存下来,然后定时重传,修复数据的不一致性。
  • 异步修复: 这个是最常用的方式,通过定时对账检测副本数据的一致性,并修复。

总结

CAP 是分布式系统设计理论,BASE 是 CAP 理论中 AP 方案的延伸,ACID 是数据库事务完整性的理论。

CAP理论严格来讲不是三选二,而是CP、AP二选一,因为通常P(分区容错性)是必须得到保证的。

BASE理论面向的是大型高可用、可扩展的分布式系统。与传统ACID特性相反,不是强一致性模型,BASE提出通过牺牲强一致性来获得可用性,并允许数据一段时间内的不一致,但是最终需要达到一致状态。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注