一、什么是 CAP 定理?
1. 定义(由 Eric Brewer 提出,后由 Lynch 等人证明)
在一个网络分区(Partition)必然存在 的分布式系统中,无法同时满足以下三个属性:
- C(Consistency)一致性:所有节点在同一时间看到的数据是相同的(强一致性,如线性一致性)。
- A(Availability)可用性:每个请求都能在合理时间内收到非错误的响应(即使部分节点故障)。
- P(Partition tolerance)分区容错性:系统在网络发生分区(节点间通信中断)时仍能继续运行。
关键结论 :P 是必须接受的现实 (网络不可靠),因此实际系统只能在 C 和 A 之间做权衡 ,即 CP 或 AP。
✅ 注意:CAP 并不是说"三选二",而是"P 必须选,C 和 A 最多只能再选一个"。
二、CAP 的作用是什么?
1. 指导架构设计
- 帮助你在系统设计初期就明确核心诉求:是要强一致?还是要高可用?
- 避免"既要又要"的幻想,比如"我要强一致 + 永不宕机 + 跨机房低延迟"------这在理论上不可能。
2. 技术选型依据
- 选数据库/中间件时,先看它是 CP 还是 AP:
- CP 系统:ZooKeeper、etcd、HBase、Consul(默认模式)
- AP 系统:Eureka、Cassandra、DynamoDB、Redis Cluster(部分场景)
3. 故障应对策略
- 当网络分区发生时,系统行为是"拒绝服务"(保 C)还是"返回旧数据"(保 A)?
三、真实业务场景中的 CAP 体现
场景 1:注册中心(服务发现)
- 需求:微服务需要快速发现彼此,即使部分节点挂了也不能阻塞调用。
- 选择 :AP
- 案例 :
- Eureka(Netflix):宁可返回可能过期的服务列表,也要保证可用。即使所有 Eureka 节点断连,客户端仍能使用本地缓存继续调用。
- 对比:ZooKeeper 是 CP,一旦 Leader 选举期间(几十秒),整个注册中心不可写,可能导致服务无法注册/发现,引发雪崩。
💡 大厂实践:Spring Cloud Alibaba 默认用 Nacos,它支持 AP(服务发现) + CP(配置管理) 混合模式,按需切换。
场景 3:支付/金融交易系统
- 需求 :账户余额、订单状态必须绝对一致,不能出现超卖或重复扣款。
- 选择 :CP
- 案例 :
- 核心账务系统通常基于 MySQL 主从 + 半同步复制 或 TiDB(Raft CP)。
- 分布式事务(如 Seata AT 模式)也以最终一致性为底线,但关键路径(如扣款)会通过锁或 TCC 强制保证一致性。
📌 注意:虽然 CAP 说 CP 牺牲 A,但可通过多副本 + 快速故障转移尽量提升可用性(如 TiDB 自动选主 < 10s)。
场景 4:社交/内容类应用(如微博、抖音)
- 需求:用户发帖后,粉丝"尽快"看到即可,允许短暂不一致;但系统必须扛住流量洪峰。
- 选择 :AP + 最终一致性
- 案例 :
- 关注 feed 流:写扩散(推模式)+ 缓存(Redis)+ 异步队列(Kafka)。
- 即使某 Redis 分片宕机,系统仍可降级返回部分数据(牺牲 C,保 A)。
✅ 用户体验优先:宁可看到"5 分钟前的动态",也不能"刷不出来页面"。
四、高级认知:CAP 的局限性与演进
1. CAP 是"极端情况"下的理论
- 它假设网络分区是"全有或全无",现实中更多是延迟升高、部分丢包。
- 实际系统往往在 C 和 A 之间做细粒度权衡(如:读保 A,写保 C)。
2. BASE 理论是对 CAP 的工程补充
- Basically Available(基本可用)
- Soft state(软状态)
- Eventually consistent(最终一致性)
- 适用于大多数互联网场景(如电商、社交)。
3. 现代系统往往是"混合模式"
- 同一系统不同模块采用不同策略:
- 用户登录 → AP(可用性优先)
- 资金转账 → CP(一致性优先)
总结
"CAP 定理告诉我们,在分布式系统中,网络分区不可避免,因此我们必须在一致性和可用性之间做出取舍。
在实际业务中,注册中心我们选 AP(如 Eureka),保证服务永远可发现;而配置中心和金融核心系统我们选 CP(如 etcd、TiDB),确保数据绝对正确。