CAP 定理
CAP 定理又称布鲁尔定理(Brewer's Theorem),是分布式系统领域最重要的理论之一,由 Eric Brewer 于 2000 年提出。它揭示了分布式系统设计中一个无法回避的取舍困境。
一、前置概念:什么是网络分区?
网络分区(Network Partition) 是指分布式系统中,因网络故障(交换机宕机、光纤中断、路由异常等)导致部分节点之间的通信被切断,系统被迫分裂成若干个相互隔离的子网络。
正常状态: 发生网络分区:
Node A ─── Node B Node A Node B
│ │ │ │
Node C ─── Node D Node C ✂ Node D
所有节点互通 A/C 与 B/D 之间通信中断关键理解
分区内的节点依然可以互相通信,但跨分区的节点无法交换数据。网络分区在真实的分布式环境中随时可能发生,因此分区容错性(P)是几乎无法放弃的前提。
二、CAP 的三个特性
C — 一致性(Consistency)
任意时刻,所有节点看到的数据完全相同。客户端无论读哪个节点,都能得到最新的写入结果。
🌰 生活类比:银行柜台和 ATM 机显示的余额必须完全一致,不能出现柜台显示 1000 元、ATM 显示 800 元的情况。
A — 可用性(Availability)
每个非故障节点都必须在合理时间内响应请求,系统不能因为部分节点异常就拒绝服务。
🌰 生活类比:即使银行某个后台系统在维护,ATM 机也应该还能正常取款,而不是直接显示"服务不可用"。
P — 分区容错性(Partition Tolerance)
即使网络发生分区,系统仍然能继续对外提供服务,不会因为节点间通信中断而整体崩溃。
🌰 生活类比:上海和北京的数据中心之间的专线断了,但两地的用户依然能正常使用系统。
三、CAP 定理的结论
核心结论
一致性(C)、可用性(A)、分区容错性(P),三者最多只能同时满足其中两个。
在真实的分布式系统中,网络分区是客观存在的,P 几乎是必须保证的。因此实际上的选择往往是:
- CP:保证一致性,牺牲部分可用性
- AP:保证可用性,牺牲强一致性(转为最终一致性)
C(一致性)
/ \
CP CA
/ \
P(分区容错)——AP—— A(可用性)
CA:传统单机数据库(不存在分区问题)
CP:ZooKeeper、etcd、HBase
AP:Cassandra(默认)、CouchDB、DNS四、应用场景与决策
场景背景
假设有一个分布式数据库集群,由于网络故障,集群被分成 分区 A 和 分区 B,两个分区内部可以正常通信,但分区之间的通信中断。
此时系统必须在 C 和 A 之间二选一(P 已无法避免)。
选择 CP:保一致性,牺牲可用性
做法:分区 B 检测到无法与主节点通信后,拒绝所有写请求,只允许主分区 A 继续提供读写服务。分区恢复后再同步数据。
效果:数据绝对不会出现冲突,但分区 B 的用户在故障期间无法写入数据。
适用系统:
- 银行转账、支付系统(余额不能出现两份不同的值)
- 库存扣减(不能超卖)
- 分布式锁、配置中心
代表中间件:ZooKeeper、etcd、HBase
选择 AP:保可用性,牺牲强一致性
做法:分区 A 和分区 B 各自继续提供读写服务,互不干扰。网络恢复后再通过数据同步机制(如"最后写入者胜出"、"向量时钟"、"合并策略")解决冲突,达到最终一致性。
效果:用户在任何时候都能访问和操作,但在故障期间可能读到稍旧的数据。
适用系统:
- 社交媒体点赞数、评论(短暂不一致可以接受)
- 购物车(用户看到的商品数量短暂有偏差无关紧要)
- DNS 解析(全球节点不强求实时同步)
代表中间件:Cassandra(默认配置)、CouchDB、DynamoDB
最终一致性
AP 模式并不是"放弃一致性",而是将强一致性降级为最终一致性——允许数据在短时间内不同步,但保证在网络恢复后最终达到一致的状态。
五、主从复制中的 CP 与 AP
CP 模式(常见于关系型数据库)
网络分区发生时,只有主节点所在分区继续提供写服务,从节点分区拒绝写入,等待主节点恢复连接后再同步。
分区前: 主(A) ──同步──> 从(B)
分区后: 主(A) 继续写入 从(B) 拒绝写入,等待恢复AP 模式(常见于 NoSQL 数据库)
网络分区发生时,主从节点各自继续接受读写,分区恢复后通过冲突解决策略进行数据合并。
分区前: 主(A) ──同步──> 从(B)
分区后: 主(A) 继续写入 从(B) 也继续写入(可能产生冲突)
恢复后: 主(A) + 从(B) 进行数据合并,达到最终一致注意
Cassandra、MongoDB 等数据库并非固定属于某种模式,它们支持通过一致性级别配置在 CP 和 AP 之间灵活调整。例如 Cassandra 设置 ALL 级别时偏向 CP,设置 ONE 级别时偏向 AP。
六、如何选择?
| 考量维度 | 选 CP | 选 AP |
|---|---|---|
| 数据错误的代价 | 极高(如资金、库存) | 可接受(如点赞数、浏览量) |
| 用户对不可用的容忍度 | 较高(等一下没关系) | 极低(必须随时可用) |
| 业务对数据实时性要求 | 严格(必须读到最新) | 宽松(稍旧也可以接受) |
| 典型业务 | 金融、医疗、电商支付 | 社交、内容、推荐系统 |