CAP 由埃里克・布鲁尔(Eric Brewer)在 2000 年提出,又叫布鲁尔定理 ,是分布式系统最基础、最重要的理论。 一句话结论:分布式系统,无法同时满足 C、A、P 三者,最多同时满足两个。

模拟一次网络分区:两个副本之间链路断开,客户端请求进来时,系统被迫二选一。
分区发生时的取舍
再看现实中各种系统落到了哪个象限------这能帮你在选型时快速定位。

一、CAP 三个字母到底指什么
C --- Consistency一致性
严格说是线性一致性:任何一次读,要么读到最新写入的值,要么报错。更直观地说------所有节点在同一时刻看到的数据是完全相同的,就像只有一份数据副本。
它和数据库 ACID 里的 Consistency 事务一致性/约束不被破坏不是一回事,别混淆。
A --- Availability可用性
指每一个非故障节点 ,收到请求后一定返回响应------且不保证响应里是最新数据。重点是"不拒绝、不超时、有回应",而不是"响应正确"。
P --- Partition tolerance分区容错性
指系统允许网络发生分区 一部分节点之间消息丢失或延,并且仍能继续对外提供服务。换句话说,系统不假设网络永远可靠。
二、定理的核心
很多人误读成CAP 让你随便放弃一个。真正的工程现实是:
- P 基本不能放弃。 任何跨网络的分布式系统,网络分区终究会发生光缆被挖断、交换机故障、GC 停顿。你无法"选择不要 P"------你只能选择当 P 发生时怎么办。
- 所以真实决策是:没有分区时,C 和 A 都能拿到正常情况三者看着都像;一旦分区发生,必须在 C 和 A 之间二选一。
这就是图二表达的意思:分区出现 → 两个副本失联 → 要么拒绝请求保一致CP,要么照常返回旧值保可用AP。
三、三种组合的真实含义
| 组合 | 含义 | 现实处境 |
|---|---|---|
| CA | 一致且可用,但无分区容错 | 实际等于单节点系统。一旦网络分区,整个系统不可用。所以"CA 系统"大多是本地/单机关系型库。在真正的分布式部署里,CA 不存在。 |
| CP | 保一致,分区时牺牲可用性 | 拒绝或阻塞那些无法确认一致性的请求。代表:ZooKeeper、etcd、HBase、Redis 主从同步复制时。适合分布式锁、选主、金融账本。 |
| AP | 保可用,分区时牺牲一致性 | 每个节点都响应,但可能返回旧值,靠后续同步收敛到一致。代表:DynamoDB、Cassandra、Riak、S3、DNS。适合购物车、缓存、日志、点赞。 |
四、误区
-
"CP 系统永远一致、AP 系统永远不一致"是错的。 没有分区时,AP 系统也能很快一致;CP 系统在正常运行时同样可用。CAP 只在分区那一瞬间强制你做取舍。
-
真实系统大多是"混合体",不是非黑即白。 例如 MongoDB 可调成强一致或最终一致;Cassandra 可调一致性级别。它们是在每个操作级别上做 C-A 权衡,而不是全局贴死一个标签。
-
一致性有强弱之分。 CAP 的 C 是"最强"的线性一致。工程上大量系统用最终一致性+ BASE 理论基本可用、软状态、最终一致 来换取更高的可用性和性能------这是 AP 系统的主流实践。
-
**CAP 只谈"分区那一刻",不谈延迟、吞吐、容错恢复。** 它是对"一致性 vs 可用性"取舍的必要但不充分条件。
补充:容易混淆的知识点
1. CAP 和 BASE 的关系
CAP 是理论约束;BASE 是 AP 系统的工程实践思想
- Basically Available 基本可用:故障时,允许部分降级 功能降级、响应变慢,但不是完全不可用
- Soft state 软状态:允许中间状态,数据不用时刻一致
- Eventually consistent 最终一致性:一段时间后数据自动一致
绝大多数互联网业务选型都是 BASE + AP
2. CAP 不描述性能!
很多人搞错:CAP 不关心快不快。 A 是能不能返回结果,不是返回快;C 是数据是否一致,不是同步快慢。
3. CAP 是 "发生分区时的取舍",不是常态下的取舍
- 网络正常、没有分区的时候,一个系统可以同时满足 C 和 A!
- CAP 的矛盾只有在网络分区故障出现时才会爆发。
正常情况下 etcd CP 也能又一致又可用;只有分区来了,它才会拒绝写入,牺牲 A 保 C。
4. 强一致 vs 最终一致
- CAP 的 C = 线性一致性 强一致
- AP 系统不是不要一致性,只是不要强一致,换成最终一致、因果一致等弱一致模型