CAP 理论

发布时间 2023-08-11 23:38:46作者: Angelia-Wang

CAP 理论基本概念

维基百科的翻译版本

在理论计算机科学中,CAP定理 (CAP theorem),又被称作布鲁尔定理 (Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  • 一致性 (Consistency):等同于所有节点访问同一份最新的数据副本;
  • 可用性 (Availability):每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据;
  • 分区容错性 (Partition tolerance):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择;
    【简单解释:分区容错性是,尽管任意数量的消息因节点间的网络问题而丢失或者延迟,系统仍能正确运行】

对于一个分布式系统来说,不可能同时满足以上三点。

image-20230811213822132

CAP 理论的理解

对于一致性:同一份 意味着所有数据节点中的数据都要是一致的,最新 意味着这些数据不能都是错误的。

对于可用性:意味着给一个成功的响应就行,获取的数据不一定是最新的。

对于分区容错性:尽管因节点之间的网络问题,任意数量的消息被丢失或者延迟(网络丢包,网络中断),系统仍能保证不崩溃(系统能够容忍这些问题)

❗️CAP 中的一致性 C 和数据库事务 ACID 特性中的一致性 C 不同。

ACID 中 C 指的是事务的一致性状态,即:数据库任何数据库事务修改数据必须满足定义好的规则,包括数据完整性 (约束)、级联回滚、触发器等。

CAP 中的 C 可理解为数据副本的一致性,即:集群中的所有副本的值都是一样的。

为什么 CAP 三者无法共存

在没有网络分区和网络波动的情况下,我们无需为了 P 而舍弃 C 或者 A;但是一个大集群中的网络几乎无时不刻都存在问题 (网络分区或者网络波动时刻发生),因此:为了保证 P (让整个分布式系统还是可用的),就要舍弃 C 和 A 中的一个。

在不考虑副本投票选举 (Quorum Replication) 和共识 (Consensus) 算法的情况下:假设存在 3 个副本,则对于这 3 个副本的写入有 2 种可能的方案:

  • \(W=1\)(一写):向 3 个副本写入,只要 1 个副本返回写入成功即认为成功;
  • \(W=3\)(三写):向 3 个副本写入,必须 3 个副本都写入成功才认为成功;

一写的情况下,由于只要有一个副本写入成功即可返回成功;当存在网络分区后 (如图 S1 的网络和其他节点中断),三台机器的数据就可能出现不一致的情况,因此无法保证 C;但由于可以正常的返回写入成功,所以 A 可以保证。

image-20230811223209713

三写的情况下,要三个副本都写入成功才可返回成功,出现网络分区的故障后,由于无法保证三个节点都写入成功,因此最终会返回报错,所以没有保证 A;但由于数据没有被成功写入,因此保证了 C。

image-20230811231332278

用 CAP 理论分析分布式数据库

前面提到,在分布式的环境下,P 一定存在。因此一旦出现了网络分区,一致性和可用性就一定要抛弃一个。

  • 对于 NoSQL 数据库,由于更加注重可用性(例如:缓存等场景),因此会是一个 AP 系统;
  • 对于分布式关系型数据库,必须要保证一致性,因此就是一个 CP 系统;

❗️虽然分布式关系型数据库是一个 CP 系统,但是仍然是具有高可用性需求的,虽然达不到理论上 100% 的可用性,但是一般都具备5个9(99.999%)以上的高可用(如通过主备切换,重新选主等,还是能恢复正常服务的)。

所以可将分布式关系型数据库看作是 CP + HA (Hign Availability) 的系统,也因此产生了两个重要且广泛使用的指标:

  • RPO (Recovery Point Objective,恢复点目标):指数据库在灾难发生后会丢失多长时间的数据。分布式关系型数据库 RPO = 0;
  • RTO (Recovery Time Objective,恢复点时间):指数据库在灾难发生后到整个系统恢复正常所需要的时间。分布式关系型数据库 RTO < 几分钟。

可以认为:

  • RPO 对应了 CAP 中的 C,因此一般情况下 RPO 都是 0,因为数据一致性是保证的,没有副本丢失数据;
  • RTO 对应 HA,虽然不能完全保证 A,但是可以达到高可用;

辩证看待 CAP 理论

CAP 理论是一个证明在现实场景下你无法达到什么的理论(即:追求CAP都保证),这个理论限制了分布式系统设计者的行为,类似于能量守恒理论限制了你无法设计出永动机。

其 C 和 A 的条件都太过极端,就导致有些理解不深入的设计者认为选取了一个,就一定抛弃了另一个。实际设计一个系统时,是要根据实际场景,在保证一个指标的同时,对另一个指标进行 降级 处理,尽量的去保证另一指标。也就是一个 tradeoff 的过程。

用 CAP 视角看目前成熟的分布式方案

前面提到了副本投票选举 (Quorum Replication) 和共识 (Consensus) 算法,这里来简单看一下。

Quorum Replication

Quorum Replication 主要包括三个部分:

  • \(N\):副本数;
  • \(W\):写入成功副本数;
  • \(R\):读取成功副本数;

\(W+R>N\) 时,在系统中永远都存在至少一个副本是最新且正确的。 因此,对于系统中的多个节点,只需要保证 \(W+R>N\) (大多数成功即成功)。

\(N=3\) 时有两种设计:

  1. \(W=1, R=3\) (写可用 AP,读一致 CP):? 记录流水系统,流水是源源不断产生并需持续写入的,因此不能容忍写入的阻塞,所以写入追求可用性;读取流水可入容许暂时失败,但不能容忍读取的流水是不正确的,因此读要保证一致性。
  2. \(W=3,R=1\) (写一致 CP,读可用 AP):? 电子商务系统,商家修改商品金额,可以容许暂时失败或阻塞,但是会有大量客户去查看商品,需要保证读可用。

Consensus

在共识算法中,各个副本之间存在交互,整个集群中会选举出一个 leader (使用 raft、paxos 算法等),由 leader 提供读写操作。

  • 当 leader 没有出现故障的情况下,整个集群的 CA 都可以得到保障。
  • 当 leader 由于部分原因宕机,集群选举新的 leader,此时系统会在选举的短暂过程中不可用;

因此,共识算法通常都是一个 CP + HA 的系统。

参考链接

宝藏 UP 戌米的论文笔记