← 返回题目列表

CAP 理论是什么?实际系统如何取舍?

高频 中等 第 13 / 27 题 更新于 2026/07/28
CAP分布式一致性可用性

简化版

CAP 指分布式系统的三个特性:一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。它真正表达的是:网络分区发生时,系统无法同时保证强一致和可用,只能在 CP 与 AP 之间取舍。因为分布式系统无法避免网络分区,所以 P 不是可选项,面试里要答成“分区时 C 和 A 的取舍”。

详细版

CAP 的三个含义要讲准确:

特性含义关键点
C 一致性所有节点对外表现得像一份数据这里通常指强一致,读到最新写入
A 可用性每个非故障节点都能在有限时间响应响应可以成功或明确失败,但不能无限等待
P 分区容错性网络把节点隔开时系统仍能处理请求跨机器通信必须考虑分区

分布式系统里,网络故障、机房隔离、交换机异常、丢包超时都可能造成分区。分区出现后,如果继续让两个分区都读写,就可能产生不一致;如果为了不产生不一致而拒绝某些请求,就牺牲了可用性。所以实际取舍是:

  • CP:分区时宁可拒绝服务,也要保证数据一致,常见于 ZooKeeper、etcd、强一致元数据系统。
  • AP:分区时尽量继续服务,允许短暂不一致,后续靠同步、冲突解决、补偿达到最终一致,常见于很多缓存、注册中心、社交类系统。

面试要避免把 CAP 简单说成“三选二”。更准确的表达是:没有分区时 C 和 A 可以同时满足;分区发生时,P 已经摆在面前,系统必须在 C 和 A 之间选一边倾斜。

完整版教学

一、先把 CAP 放进一个真实场景

假设订单服务有两个副本,A 在上海机房,B 在北京机房。正常情况下,用户扣库存写到 A,数据同步到 B,两个机房都能读到同样的库存。现在两个机房之间网络断了,A 和 B 互相不知道对方的最新状态,这就是网络分区。

此时北京用户访问 B,如果 B 继续扣库存,系统可用性很好,但 A 和 B 可能同时卖出最后一件商品,库存就不一致了。如果 B 为了保证不超卖而拒绝写请求,就保护了一致性,但北京用户看到的是服务不可用。CAP 的矛盾就出现在这一刻:不是平时不能一致又可用,而是分区时无法同时做到“继续服务”和“绝不产生分歧”

二、为什么 P 不是你想不想选的问题

很多初学者会问:我能不能选 CA,不要 P?在分布式系统里这基本没有意义。只要服务跨机器、跨网络、跨机房,分区就可能发生。你可以说“我暂时不处理分区,一分区就整体不可用”,但这相当于系统没有分区容错能力,不是一个可靠的分布式设计。

所以工程上不会问“要不要 P”,而是问:“当 P 发生时,业务更怕什么?”如果更怕脏数据、重复扣款、超卖,就偏 CP;如果更怕服务不可用、用户无法浏览、服务发现完全瘫痪,就偏 AP。

三、CP 系统牺牲的不是全部可用,而是部分请求

CP 不等于整个系统挂掉。它的做法通常是让无法确认多数派、无法确认主节点身份、无法确认最新数据的节点停止对外写入,甚至停止提供强一致读。比如 etcd/Raft 集群中,如果某个少数派分区没有 Leader,它就不能接受写请求,因为它无法保证这个写会被集群承认。

这样做的代价是:一部分节点明明还活着,却不能响应某些请求。好处是:系统不会产生两个权威结果,不会出现两个 Leader 同时写配置、两个库存中心同时扣库存这样的灾难。

四、AP 系统牺牲的不是永远一致,而是实时一致

AP 也不是“数据随便乱”。AP 的核心是先保服务,允许副本在一段时间内不一致,等网络恢复后通过同步、版本比较、冲突合并、补偿任务让数据收敛。比如用户点赞数、浏览量、推荐候选集、服务注册表,短时间旧一点通常可以接受。

AP 系统真正难的是冲突处理。两个分区都写了同一份数据,恢复后谁覆盖谁?常见策略有最后写入胜出、版本号比较、向量时钟、业务合并、人工介入。AP 的成本不是没有成本,而是把成本从“请求当场等待一致”转移到“后台修复和冲突解决”。

五、CAP 与 PACELC 的关系

CAP 只讲分区时的取舍,但系统大部分时间没有分区。PACELC 把问题补完整:如果发生 Partition,就在 Availability 和 Consistency 之间取舍;Else 没有分区时,也要在 Latency 和 Consistency 之间取舍。强一致读写通常要等待复制确认,延迟更高;最终一致通常延迟更低,但可能读到旧数据。

面试答到 PACELC,会显得你不是背概念,而是在做系统设计。真实系统往往是:核心链路局部 CP,外围链路偏 AP;写链路更强一致,读链路通过缓存和副本降低延迟。

六、面试追问怎么接

如果面试官问“Redis、MySQL、ZooKeeper 是 CP 还是 AP”,不要机械贴标签。要说明具体模式和场景:ZooKeeper/etcd 的一致性协议偏 CP;Redis 主从默认异步复制,故障切换时可能丢数据,更偏可用和低延迟;MySQL 单主强一致事务在单库内成立,跨机房复制通常又涉及延迟和一致性取舍。CAP 是分析框架,不是给产品永久贴一个字母标签。

七、常见误区与追问

这道题不能只背概念,要把「CAP 定理」放回真实分布式系统里解释:谁发起、谁协调、状态如何变化、失败后怎么兜底,以及它和性能、可用性、一致性的取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论CAP 说网络分区发生时,一致性 C 和可用性 A 不能同时完美满足,P 是分布式系统必须面对的前提不要停在名词解释
流程机制出现网络分区 -> 判断是否继续响应请求 -> 若继续响应可能读写旧数据 -> 若拒绝响应保持一致但不可用 -> 结合业务选择 CP 或 AP说明触发方、参与方、状态变化和兜底
工程取舍3 节点系统若 1 个节点与另外 2 个节点网络隔离,继续两边都写会破坏 C,拒绝一边写会牺牲 A分布式基础题不能只背概念,必须落到网络不可靠、节点会故障、数据有副本这些前提
CAP 定理 面试拆解:
1. 出现网络分区
2. 判断是否继续响应请求
3. 若继续响应可能读写旧数据
4. 若拒绝响应保持一致但不可用
5. 结合业务选择 CP 或 AP

记忆钩子:先定义问题,再说明一致性、可用性、分区、复制、时钟和故障模型的取舍;回答时要紧扣「CAP 定理」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:CAP 是 C、A、P 三选二。 严格说分布式系统必须容忍 P,分区发生时才在 C 和 A 之间取舍。
  • 误区:牺牲一致性就是数据错误。 AP 系统通常牺牲的是强一致,仍会通过同步、重试和修复达到最终一致。
  • 误区:数据库强一致就不用考虑 CAP。 跨节点复制和网络分区仍然存在,强一致会以可用性或延迟为代价。
  • 追问:注册中心为什么常说选 AP? 因为服务发现更怕完全不可用,短暂旧地址可由客户端重试和健康检查兜底。
  • 追问:什么时候更偏 CP? 库存、余额、配置元数据等不能接受旧值写入的场景更偏 CP。
  • 追问:CAP 和 BASE 有什么关系? BASE 是在 AP/最终一致方向上的工程思想,接受软状态换取可用性。

八、加强记忆

CAP 要记成一句工程话:分布式必须面对网络分区,分区发生时,如果继续服务就可能不一致,如果保证强一致就必须拒绝部分请求。所以真正选择是 CP 还是 AP,不是简单“三选二”。钱、库存、锁、元数据通常偏 CP;点赞、浏览、推荐、服务发现常常偏 AP;更完整的设计还要用 PACELC 思考平时的一致性与延迟权衡。