跳到主要内容

CAP 与 BASE 理论

问题

什么是 CAP 定理?什么是 BASE 理论?分布式系统中如何在一致性和可用性之间做权衡?

答案

CAP 定理

CAP 定理(又称布鲁尔定理)指出:在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)三者最多只能同时满足两个

属性含义
C(Consistency)所有节点在同一时刻看到的数据一致(强一致性)
A(Availability)每个请求都能在合理时间内收到非错误响应
P(Partition Tolerance)网络分区(节点间通信中断)时系统仍能运行
为什么必须选择 P?

在分布式系统中,网络分区是不可避免的(网线可能断、路由器可能故障)。因此 P 是必选项,实际选择是 CP 还是 AP

  • CP:分区时拒绝部分请求,保证返回的数据一定正确(如 ZooKeeper 选举期间不可用)
  • AP:分区时继续提供服务,但返回的数据可能不是最新的(如 Eureka 的自我保护模式)

CAP 的实际案例

BASE 理论

BASE 是对 AP 方案的延伸,核心思想是 放弃强一致性,追求最终一致性

概念英文含义
BABasically Available基本可用:分布式系统出故障时,允许损失部分可用性(响应时间变长、功能降级)
SSoft State软状态:允许系统中存在中间状态,即数据副本之间存在短暂不一致
EEventually Consistent最终一致性:经过一段时间后,数据副本最终会达到一致

ACID vs BASE

对比ACIDBASE
适用范围单机数据库事务分布式系统
一致性强一致性最终一致性
可用性不做保证基本可用
代表MySQL 事务NoSQL、微服务
思想悲观,严格正确乐观,允许中间状态

一致性级别

级别说明示例
强一致性写入后立即可读到最新值CP 系统、分布式事务
弱一致性不保证何时能读到最新值UDP 通信
最终一致性一段时间后一定能读到最新值DNS、Redis 主从、Eureka
因果一致性有因果关系的操作有序社交网络评论
读己之写自己写的数据能立即读到用户昵称修改后自己能看到
会话一致性同一会话内保证一致Session Sticky

常见面试问题

Q1: CAP 为什么不能同时满足?

答案

假设两个节点 N1、N2 之间发生网络分区:

  1. 客户端向 N1 写入数据
  2. N1 无法将数据同步到 N2(网络断了)
  3. 此时客户端去 N2 读取:
    • 若要保证 一致性(C):N2 必须拒绝响应或等待同步完成 → 牺牲了可用性(A)
    • 若要保证 可用性(A):N2 返回旧数据 → 牺牲了一致性(C)

在网络分区(P)存在的前提下,C 和 A 必然矛盾。

Q2: ZooKeeper 是 CP 还是 AP?

答案

ZooKeeper 是 CP 系统:

  • Leader 选举期间(约 30s~120s),集群不对外提供写服务 → 牺牲可用性
  • 写入必须过半节点确认,保证数据一致性
  • 读可以从 Follower 读,可能读到旧数据(若需强一致读用 sync() 命令)

对比 Eureka 是 AP:节点间互相注册,任何节点宕机不影响服务发现,但可能返回过期的服务列表。

Q3: 如何在一致性和可用性之间权衡?

答案

根据业务场景选择:

  • 金融/支付:选 CP,宁可不可用,不能数据错误(分布式事务、强一致性)
  • 社交/电商展示:选 AP,允许短暂看到旧数据,保证服务可用(最终一致性)
  • 库存扣减:核心操作用 CP(强一致),库存展示用 AP(最终一致)

实践中通常是 混合方案:核心链路保证强一致,非核心链路接受最终一致。

Q4: 什么是最终一致性?怎么实现?

答案

最终一致性是指:数据更新后,经过一段时间(通常秒级),所有副本最终会达到一致状态。

常见实现:

  1. 异步复制:主库写入后异步同步到从库(MySQL 主从、Redis 主从)
  2. 消息队列:通过 MQ 异步通知下游更新数据
  3. 定时对账:定时比对上下游数据,修复不一致
  4. 反熵(Anti-Entropy):节点间定期互相对比数据、修复差异(如 Cassandra)

相关链接