知识模块
☕ Java 知识模块
九、分布式系统
CAP 理论与 BASE 理论

CAP 理论与 BASE 理论

CAP 定理

CAP 定理由 Eric Brewer 提出:分布式系统最多只能同时满足三项中的两项。

属性说明
C (Consistency)一致性:所有节点同一时间看到相同数据
A (Availability)可用性:每个请求都能在合理时间内得到响应
P (Partition Tolerance)分区容错:网络分区时系统仍能运行

CAP 三角

        C (一致性)
       /\
      /  \
     /    \
    /______\
 A (可用性) —— P (分区容错)

三种组合

组合说明典型系统
CA一致性 + 可用性(无分区容错)单机数据库(MySQL、PostgreSQL)
CP一致性 + 分区容错Redis、HBase、Zookeeper
AP可用性 + 分区容错Cassandra、DynamoDB、Eureka

为什么只能三选二?

网络分区是必然发生的,所以 P 必须选。实际是在 C 和 A 之间做选择:

网络分区发生时:

选择 C (一致性):
┌─────────────────────────────────┐
│ 节点A ←──网络断开──→ 节点B     │
│ 数据: v1              数据: v2  │
│                                 │
│ 为了保证一致性,拒绝写入请求   │
│ → 牺牲可用性                    │
└─────────────────────────────────┘

选择 A (可用性):
┌─────────────────────────────────┐
│ 节点A ←──网络断开──→ 节点B     │
│ 数据: v1              数据: v2  │
│                                 │
│ 继续接受写入,允许数据不一致   │
│ → 牺牲一致性                    │
└─────────────────────────────────┘

BASE 理论

BASE 是对 CAP 中 AP 方案的延伸,通过牺牲强一致性获得高可用性。

属性说明
BA (Basically Available)基本可用:允许部分不可用
S (Soft State)软状态:中间状态允许存在
E (Eventually Consistent)最终一致:一段时间后达到一致

最终一致性

时间线:

T1: 用户A写入 name = "张三"
    ┌──────┐  ┌──────┐  ┌──────┐
    │ 节点1 │  │ 节点2 │  │ 节点3 │
    │ 张三  │  │ null  │  │ null  │
    └──────┘  └──────┘  └──────┘

T2: 异步复制中...
    ┌──────┐  ┌──────┐  ┌──────┐
    │ 节点1 │  │ 节点2 │  │ 节点3 │
    │ 张三  │  │ 张三  │  │ null  │
    └──────┘  └──────┘  └──────┘
    
    此时用户B查询可能得到不同结果

T3: 最终一致
    ┌──────┐  ┌──────┐  ┌──────┐
    │ 节点1 │  │ 节点2 │  │ 节点3 │
    │ 张三  │  │ 张三  │  │ 张三  │
    └──────┘  └──────┘  └──────┘

最终一致性的级别

级别说明示例
因果一致性有因果关系的操作顺序一致A→B→C 链式操作
读己之所写自己写入的数据自己能读到微博发帖后能看到
会话一致性同一会话内一致购物车会话
单调读一致性读取数据不会倒退消息已读状态
单调写一致性写操作顺序一致版本号递增

强一致性 vs 最终一致性

对比强一致性最终一致性
实现难度
性能
可用性
适用场景金融交易、库存社交、日志
典型系统MySQL、ZookeeperCassandra、Eureka

应用场景选择

场景决策:

是否要求强一致?

    ├── 是 → 选择 CP(Zookeeper、Redis)
    │        金融交易、库存扣减、账户余额

    └── 否 → 选择 AP(Eureka、Cassandra)
             社交动态、商品评论、日志收集

面试高频问题

Q1: 为什么 CAP 只能三选二?

网络分区是分布式系统必须面对的现实问题,所以 P 必须选。当网络分区发生时,系统必须在 C 和 A 之间做选择。

Q2: BASE 和 ACID 的区别?

对比ACIDBASE
目标强一致性最终一致性
场景单机事务分布式系统
复杂度
性能

Q3: 如何实现最终一致性?

  1. 消息队列:异步消息确保最终送达
  2. 定时任务:定期检查并修复不一致
  3. 版本号:通过版本号解决冲突
  4. 补偿机制:失败时执行补偿操作

总结

CAP/BASE 核心要点:
1. CAP:一致性、可用性、分区容错三选二
2. P 是必选项,实际在 C 和 A 之间选择
3. CP 系统:Zookeeper、Redis、HBase
4. AP 系统:Eureka、Cassandra、DynamoDB
5. BASE:基本可用 + 软状态 + 最终一致