CAP定理是分布式系统的基石,其严格的定义为:在一个异步网络(Asynchronous Network)中,如果发生网络分区(P),系统必须在强一致性(C)和完全可用性(A)之间做出取舍。

此处强调“异步网络”,并不是预设有“异步网络”和“同步网络”两个场景,而是为了驳斥经典谬误“C、A、P同时只能成立两个”。因为在同步网络下,C和A是可以同时成立的,而现实世界中并没有完美的同步网络。

异步网络(为什么没有同步网络)

分布式系统中,异步网络指数据传输时长没有绝对上限的网络。

此处“没有绝对上限”强调无法确定数据仍在缓慢地传输还是传输已经中断。

由于数据传输时间不可知,故无法确定上限。

这包含了两层含义:既无法知道过去的网络传输耗时,也无法预测将来的网络传输耗时。当然,关键在于将来的传输耗时,因为系统节点都是在实时中决策的。

过去耗时不可知

要计算一次数据传输的时间,理论上只需要通过接收时刻-发送时刻即可,而发送方只知道发送时刻、接收方只知道接收时刻,又由于时钟偏移,两方时刻永远无法统一,也就无法算出真实耗时。

此处时钟指节点本地的单调递增计数器(硬件晶振驱动的计时器)。不同节点的计数器起点(原点)不同,且走速(频率)不同的现象称为时钟漂移。

即使能完美知道过去耗时也无济于事,这并不能用来推算未来耗时。

未来耗时不可知

由于现实世界的各种情况(比如动态路由),永远没有两次完全相同的数据传输,那也就不可能估测下一次数据传输的耗时。

可能会有人问:HTTP 不是有超时时间吗?实际上在编码中,“超时”更应当认为是接收端愿意等待的时间。


在澄清了异步网络后,才能真正深入地理解CAP。

名词解释:

  • 分区容错性(Partition Tolerance):当分区发生时,系统不能无限期地“傻等”或“死锁”。实际暗含了A和C的二选一;

网络分区指原先多节点连通的分布式系统因为某些故障(比如部分节点网络出了问题)某些节点之间不连通了,整个网络就分成了几块区域。

  • 一致性(Consistency):在 Gilbert/Lynch(2002)的证明语境里,CAP 的一致性 C 指的是 Atomic Consistency,通常等同于 Linearizability(线性一致性)。即所有操作按实时顺序线性化,即写操作一旦完成,后续所有读操作都必须返回该写入的值(或更新的值)。注意:这里的 Consistency 与数据库 ACID 中的 Consistency(一致性约束)含义不同,后者指事务执行前后数据库状态满足完整性约束。

  • 可用性(Availability):非故障的节点必须对每个请求返回响应(不讨论响应快慢)。注意:这是 CAP 理论中的严格定义,不包含工程中的延迟/SLA 指标(如「1s 内返回」)。

经典谬误“三选二”中暗含的,对于“分区容忍性”之否定的情况,只能被理解为对于网络分区不可知性的否定,进而对于异步网络的否定,而非对于容忍性的否定。因为这个不可知性,恰恰是容忍性的前提。

在CAP定理问世之前(2000年之前),工程师面对网络卡顿,普遍有一种天真的想法:

“我只要把超时时间设得足够长,或者把重试机制写得足够复杂,就既能保证数据绝对不丢(C),又能保证用户永远不报错(A)”

通过前文的阅读,我们能发现网络分区在现实中也是不可预测的。CAP定理真正的历史贡献,在于让架构师们不再纠结于“网络断没断”,而是聚焦于网络分区后的抉择。

在这个前提下,也就能得知所有的分布式算法(Raft、Paxos、Spanner、Cassandra)都是在试图绕过网络分区的判定,并调和A、C的矛盾。

局限性

CAP定理并不是一个“万能公式”,它只聚焦于微观层面,主要讨论单个数据对象在副本复制场景下的一致性与可用性权衡。

CAP定理应用的范围需要满足以下三个硬性条件:

  • 数据模型:仅限单个数据对象(比如一个Key,或者一行数据),绝不涉及多行、多表或事务。
  • 操作类型:仅限原子读/写,不涉及复杂计算或聚合。
  • 副本关系:仅限于主从/多副本同步复制场景。

当视野放宽到整个宏观系统时,应当认识到:系统绝大部分时间内,矛盾并不来源于“分区”,而是来源于“延迟”、“锁冲突”、“事务隔离级别”。

PACELC理论(CAP 的扩展)

Daniel J. Abadi 提出的 PACELC 理论指出:如果存在分区(P),必须在可用性(A)和一致性(C)之间选择;否则(E,Else),必须在延迟(L)和一致性(C)之间选择。

PACELC 理论补充了CAP的局限,即使无网络分区,分布式系统仍需在低延迟(异步复制)和强一致(同步复制)之间权衡。

此处的“存在分区”和“否则”看似是两种情况,但实际上由于分区的不可预测性,架构师往往会采用一致的策略:只存在PC/EC和PA/EL,不存在PC/EL和PA/EC。

从设计哲学方向上看:

PC/EC默认网络是不好的,所以即使在网络正常的绝大多数时候,也强制使用“同步复制”,导致延迟较高,但绝对安全。

PA/EL默认网络大概率是好的,所以在网络正常的时候,采用“异步复制”,追求极致的低延迟,但需要业务层容忍最终一致性。

选择 CP 还是 AP 的关键在于当前的业务场景,没有定论:对于需要确保强一致性的场景(如分布式锁、配置管理)会选择 CP;对于高可用优先的场景如微服务注册中心会选择 AP。

业务中的应用

业务开发者虽然不需要实践 CAP 理论,但必须理解 CAP 理论,以便:

  • 为不同业务场景选择合适的组件(CP 或 AP)
  • 理解所选组件在网络分区时的行为特征
  • 设计符合业务需求的容错机制(重试、熔断、降级)