Skip to content

CAP 理论与系统设计

分布式系统有三盏灯,但只能亮两盏。

这就是 CAP 理论告诉我们的:一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance),你最多只能同时满足两个。

等等,分区容错性怎么能不选呢?

简单来说:网络分区是必然的。你的服务器可能跨机房、跨机房甚至跨地域,光纤可能被挖断,路由器可能抽风。在分布式系统中,P 不是可选项,是必选项。

所以,CAP 理论本质上是在问:C 和 A,你选哪个?

一致性 vs 可用性:没有标准答案

CP 系统:牺牲可用性换一致性

典型代表:ZooKeeper、etcd、HBase

想象银行的转账系统:你的账户余额是 100,转给朋友 50。如果系统不一致,你可能付两次 50 都成功——这叫「双花」,是灾难性的。

java
// ZooKeeper 的写操作是强一致的
// 如果 leader 宕机,写操作会失败(不可用)
// 但一旦返回成功,数据一定是一致的
public class ZKExample {
    public void write(Data data) {
        // 写入需要多数节点确认
        // 如果网络分区,部分请求会失败
    }
}

适用场景:金融交易、库存管理、分布式锁

AP 系统:牺牲一致性换可用性

典型代表:Cassandra、DynamoDB、Redis Cluster

想象微博的时间线:少刷到一条微博,用户感知不强;但如果服务器挂了,用户打开白屏,那才是灾难。

java
// Cassandra 采用最终一致性模型
public class CassandraExample {
    public void write(String key, String value) {
        // 写入本地节点即可返回成功
        // 数据会异步复制到其他节点
        // 短暂不一致,但最终一致
    }

    public String read(String key) {
        // 读请求可能返回旧数据
        // 但系统保证可用
    }
}

适用场景:社交 feed、评论系统、日志收集

你真的理解「一致性」吗?

很多人在面试中说「我要保证强一致性」,但追问下去就懵了。

一致性的三个层次

级别说明例子
强一致性写入后立即可读同步复制
弱一致性写入后可能读到旧值异步复制
最终一致性写入后最终能读到DNS、 Cassandra

实际工程中:几乎没有人用强一致性,成本太高。大多数系统用的是「最终一致性 + 补偿机制」。

跨时代的 BASE 理论

CAP 理论太理论化,实际落地需要具体方法论。BASE 理论就是 CAP 中 AP 的工程实践:

  • Basically Available:基本可用,允许偶尔失败
  • Soft state:软状态,数据可以是中间状态
  • Eventually consistent:最终一致性,允许延迟但最终一致
java
// BASE 思想下的订单服务
public class OrderService {
    // 1. 先标记「处理中」
    public void createOrder(Order order) {
        order.setStatus(OrderStatus.PROCESSING);
        orderDao.save(order); // 写入即可用

        // 2. 异步处理实际业务
        messageQueue.send(order);

        // 3. 最终状态由消费者更新
        // 这个过程可能有延迟,但最终一致
    }
}

面试中的回答套路

面试官问 CAP,不是想听你背定义,而是想看你能不能结合具体场景做决策

错误回答

「CAP 理论说一致性、可用性、分区容错性只能满足两个,我们要根据场景选择。」

这种回答等于没说。

正确回答

「对于短链接系统,我选择 AP 模型。原因有三:

  1. 用户点击短链接,系统必须高可用,卡一下用户就跑了
  2. 点击统计允许短暂不一致,差个几十条数据不影响业务
  3. 通过消息队列做异步补偿,可以保证最终一致性

但对于账户余额这类场景,我会选择 CP。」

追问

  • 「如果你的 AP 系统出现数据冲突怎么办?」
  • 「怎么设计补偿机制?」
  • 「如何让用户感知不到不一致?」

这些问题没有标准答案,考的是你对一致性的深层理解。

总结

CAP 理论不是教条,是思考框架:

  1. P 是必选的:网络分区必然发生
  2. C 和 A 看场景:金融选 C,社交选 A
  3. 大部分系统是 AP + 最终一致性:BASE 理论是工程实践
  4. 一致性有层次:强一致成本高,弱一致更实用

下次被问到 CAP,别急着回答「我选 AP」或「我选 CP」。

先问自己:这个系统里,什么数据是一致性优先的,什么数据是可用性优先的?

答案可能让你意外:同一个系统,C 和 A 可以并存——只需要分清哪些数据走 CP,哪些走 AP。

基于 VitePress 构建