CAP 理论基本概念
在理论计算机科学中,CAP定理 (CAP theorem),又被称作布鲁尔定理 (Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性 (Consistency):等同于所有节点访问同一份最新的数据副本;
- 可用性 (Availability):每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据;
- 分区容错性 (Partition tolerance):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择;
【简单解释:分区容错性是,尽管任意数量的消息因节点间的网络问题而丢失或者延迟,系统仍能正确运行】
对于一个分布式系统来说,不可能同时满足以上三点。
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 可以保证。
三写的情况下,要三个副本都写入成功才可返回成功,出现网络分区的故障后,由于无法保证三个节点都写入成功,因此最终会返回报错,所以没有保证 A;但由于数据没有被成功写入,因此保证了 C。
用 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\) 时有两种设计: