简单系统设计 —— CAP理论(八)

简单系统设计 —— CAP理论(八)

本系列,是自己学习Grokking the System Design过程中的笔记。
希望读者在看完全文后,也能留下你们的经验。我万分荣幸能收到你们的消息。
如果能从这里学到点东西,记得请我喝杯☕☕☕~

—— MinRam

一、前言 Overview

CAP理论,也叫Brewer理论,最早由Eric Brewer在2000年的the Principles of Distributed Computing会议上发表的Towards Robust Distributed Systems,并在两年后由麻省理工学院分布式系统研究人员 Seth Gilbert 和 Nancy Lynch 教授,在Brewer’s conjecture and the feasibility of consistent, available, partition-tolerant web services中证明了猜想。

CAP理论,是针对于分布式系统(共享数据的互联节点集群中,其节点应为有状态的),我们只能在系统的/对中获得三个保证(一致性、可用性和分区容错)中选择两个。总会有一个特性无法被保证。

CAP理论, 可以认为是分布式系统设计的统一纲领之一。而统一纲领,就类似一种约定,解决了分布式系统中不同模块、不同开发人员,在公共层面上能有一系列原则来指导设计,避免一些设计冲突。

比如,在分布式系统中,服务依赖问题,每个服务都是由各自的开发人员开发,导致处理策略也将不同:

  • A服务,在请求服务失败后,处理策略是不断重试;
  • B服务,在请求服务失败后,处理策略是记录错误,不再尝试连接;
    当AB之间的网络出现问题,导致服务请求失败时,就会有各自的处理方式,进一步可能导致业务失败,这就会造成模块方面的不可用。

不同的处理策略

二、理论内容 Threorem

CAP理论,说明一个分布式系统中不能同时满足三种特性。

1. C: 数据一致性 Consistency

数据一致性,要求的就是数据能保持整齐一致,能一致地变化。

  • 数据是哪来的? 前面提到,CAP理论针对的是有状态且共享数据的互联节点集群,数据自然是指节点中存储的数据。在实际分布式系统中,除了分布式数据库外,每个服务集群都会存储有状态的数据。

  • 数据何时会变化? 既然要求数据保持一致,那么保证变化一致,就可以达到这样的目的。那么加上对象,仅当存储共享数据的服务节点,收到数据更新请求(增删改)后,数据才会变化

  • 如何确定数据是一致性的? 数据只有被用到才能确定是一致的,也就是读操作

数据一致性的判断就是在一次写入操作后,通过读操作,能获取到各个节点的共享数据,且数据应是一致的且是变换后的数据。

数据一致性

但是系统不是永远都是正常运行的!如果系统内部发生了问题,导致部分节点无法更新变化。这时候,就意味着想看到最新数据的读请求们,很可能会得到旧数据(不同版本的数据)。此时,为了保证分布式系统对外的数据一致性,于是选择不返回任何数据

这个时期,系统是处于不可用状态下的。

故障场景

CAP 定理是在某种状态下的选择,跟实际工程的理论是有差别的。
上面描述的一致性和 ACID 事务中的一致性是两回事。事务中的一致性包含了实际工程对状态的后续处理。但是 CAP 定理并不涉及到状态的后续处理,对于这些问题,后续有 BASE 理论等工程结论去处理。

稍微实践系统下的一致性:

  • 一致性的强弱
    实际系统中,往往会选择中庸的答案,会根据业务场景选择对应的强度的一致性要求。
    • 弱一致性:在写入之后,访问可能看到,也可能看不到(新数据)。只是尽力优化之让其能访问最新数据。这种方式可以 memcached 等系统中看到。弱一致性在 VoIP,视频聊天和实时多人游戏等真实用例中表现不错。打个比方,如果你在通话中丢失信号几秒钟时间,当重新连接时你是听不到这几秒钟所说的话的。
    • 最终一致性: 在写入后,访问最终能看到写入数据(通常在数毫秒内)。数据被异步复制。 DNS 和 email 等系统使用的是此种方式。最终一致性在高可用性系统中效果不错。
    • 强一致性:在写入后,访问立即可见。数据被同步复制。文件系统和关系型数据库(RDBMS)中使用的是此种方式。强一致性在需要记录数据的系统中运作良好。

2. A: 可用性 Availability

系统所能体现的价值,就是操作

可用性,在 CAP 里就是对操作结果的要求。它要求系统内的节点们接收到了无论是写请求还是读请求,都要能处理并给回响应结果。

同时还应满足三个常见的要求:

  • 既然是请求,就会有返回延迟,可用性对请求到拿到结果的耗时应在合理范围内(由业务定义)。
  • 如果节点能正常接收请求,那么就一定需要返回结果,不应忽略客户端的请求,即便数据是错误的或者并非最新的。
  • 如果节点不能正常接收请求,那么一定由其他平级节点能够代替处理请求。

数据可用性

3. P: 分区容忍性 Partition Tolerance

网络是不可靠的

分布式系统中,各个节点之间是通过网络连接的,而网络是不可靠的(延迟,丢包,断连)。当网络出现问题时候,系统中就会出现不同数据版本的分区,当然也有其他原因(如网卡故障,节点超负荷等)。也就是当各节点通信出现问题后,就会出现分区

数据分区

分区容忍性,即系统在出现分区后,仍应该能够容忍这种错误,继续运行,并提供服务。

三、CAP简易证明

CAP原理指出,分布式系统是无法同时满足以上三个特性。

例如,假设我们有一个简易分布式系统(由服务器节点$S_1$和$S_2$构成),同时满足一致性可用性分区容忍性

  1. 假设有网络故障,因为我们的系统是分区容错的,它应该可以工作。在网络故障期间,客户端向服务器$S_1$发送写请求。$S_1$ 将接收请求并处理它。

  2. 如果我们的系统是一致的,$S_1$必须在向客户端确认之前更新$S_2$中的值,但由于网络故障,$S_1$ 无法更新 $S_2$。在这种情况下,对 $S_1$ 的请求将超时,这意味着我们的系统不可用。

  3. 如果我们的系统可用,$S_1$将响应客户端,而无需等待$S_2$中的更新。如果任何客户端向$S_2$发出相同信息的读取请求,它将收到较旧的值,而不是最近写入的结果。这意味着我们的系统在可用时无法保持一致。

四、 CAP的选择

在分布式系统中,分区容忍性P是必须的。没有分布式系统可以避免通讯故障。所以我们必须保障系统在存在分区时仍正常提供服务。第二个选项就只能是一致性Consistency和可用性Availability

CAP 定理经常被误解为必须始终在三个保证中选择两个。实际上,只有在网络分区或发生故障时,才需要在一致性和可用性之间进行选择。在没有网络分区或网络故障的情况下,可以同时满足可用性和一致性。

在存在分区的情况下,剩下两个选项一致性和可用性。

  • APAvailability and Partition tolerance):当可用性高于一致性时,系统将始终处理客户端请求并尝试返回最新可用版本的信息,即使由于网络分区而无法保证它是最新的。比如Spring Cloud中的Eureka
    Eureka

  • CP(Consistency and Partition tolerance): 当一致性高于可用性时,如果系统出现分区,系统将对客户端的请求返回错误或超时。比如Zookeeper
    Zookeeper

采用ACID保证 (RDBMS)设计的数据库系统通常选择一致性而不是可用性,而采用BASE保证设计的系统则选择可用性而不是一致性。

其实在实际工程中,可用性和一致性并不是完全对立的,我们往往关注的是如何在保持相对一致性的前提下,提高系统的可用性。至于是使用CP或者AP架构,则取决于业务对一致性的要求。

五、从CAP到BASE

Epay 的架构师 Dan Pritchett 根据他自身在大规模分布式系统的实践经验,总结出了 BASE 理论。

BASE 理论是对 CAP 理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。这是基于实践工程的理论,它弥补了CAP 理论过于抽象的问题,也同时解决了 AP 系统的总体工程实践思想,是分布式系统的核心理论之一。

后续有机会再补充BASE理论, 笔者精力有限,接下来会开始学习Linux系统内容。

>- 已阅留爪 (ฅ´ω`ฅ)- 可能会有的《系列总结》 -<

简单系统设计 —— CAP理论(八)

https://minram.github.io/xi-tong-she-ji/systemdesign-08-cap/

作者

MinRam

发布于

2022-01-09

更新于

2022-07-17

Licensed under

评论