CAP 定理是理解分布式系统的起点,起源于2000 年 7 月,加州大学伯克利分校的 Eric Brewer 教授于“ACM 分布式计算原理研讨会(PODC)”上提出的一个猜想。
CAP 其实指的是 :
- Consistency
- Availability
- Partition tolerance
这三个指标的首字母组合而成。它们分别代表的是 C:一致性, A:可用性, P:分区容忍性。
根据 CAP 定理,这三种特性在分布式系统中无法同时满足!也就是说,最多只能同时满足两个!
这三个指标的具体含义如下:
一致性(Consistency):代表数据在任何时刻、任何分布式节点中所看到的都是符合预期的;
可用性(Availability):代表系统不间断地提供服务的能力;
分区容忍性(Partition Tolerance):代表分布式环境中部分节点因网络原因而彼此失联后,即与其他节点形成“网络分区”时,系统仍能正确地提供服务的能力。
这里需要指出的是,通常系统在分布式部署的条件下,一般会位于多个不同的子网络内。对每个子网络,我们称之为 分区(Partition)。由于网络延迟或者中断等等可能出现的情况,各系统间无法通信的情形在上述条件下是可能出现且无可避免的。因此在系统设计的伊始阶段,总是需要将这种情况考虑在内,也就是说,CAP 中的 P 应该总是成立的。换句话讲,CAP 定理 只能要么同时满足 AP,要么满足 CP. 于是乎,就出现了以下这个问题:
这里的 A 和 C 为何就不能同时成立呢?
原因即上边提到的可能通讯失败的情形(由于网络异常)。
为了讲清楚这个问题,我们先就 可用性(A) 和 一致性(C) 的情况举个具体的例子:
假设有两个服务集群节点,设为 S1 和 S2,它们分属于不同的网络。
用户对该服务发起请求,请求由于负载均衡可能会分发到S1去处理,也可能分发到S2去处理,假设此处概率权重相等。
此时,用户申请向服务集群写入新数据 D1(类比于提交表单等等操作),此处假设请求分发到了S1,且原来的旧数据为D0,写入完成后马上读取该数据D1,如果用户读取到的就是D1,说明系统满足一致性的要求。
但是当用户再次请求读取数据D1时,有可能这次读请求分发到 S2 去处理,而 S2 上读取到的依然是旧数据 D0, 用户两次读操作却返回了不同的结果,这就不满足一致性的要求了。
可用性指的是,当用户发起请求时,无论这个请求被分发到S1或者S2,无论这个请求是否能被正常处理,都应该得到响应内容。否则系统不满足可用性要求。
接下来就可以说明 A 和 C 的矛盾之处了:
如果要确保一致性的话,意味着 新数据 D1 需要由 S1 同步给 S2,而 S2 在同步的过程中,会锁住该数据,为了避免后续的读请求读取到旧数据,此时S2 是不能对外提供读请求响应服务的,即此处 S2 无可用性可言。只有等到数据同步完成后,后续的读请求才能够读到正确的新数据,体现了系统的一致性!为了实现这个目标,我们不得不牺牲同步过程中 S2 的可用性。
如果要追求可用性的话 —— 即要求系统对每个请求都能作出响应,那么由于上述数据同步过程中可能出现网络阻塞或者延迟等等情况,从而导致数据无法及时同步,这就可能带来多次读操作会读取到不同的响应内容的后果。也就是牺牲了系统的一致性保证。
综上,根据 CAP 定理,我们只能最多同时确保 AP 或者 CP , 而无法做到三者兼顾!
参考链接: