1. 缓存一致性基础:定义、产生原因与 CAP 体现
1.1 缓存一致性问题定义
缓存一致性(Cache Coherence)是指在多核处理器系统或分布式缓存系统中,当多个副本持有同一份数据的缓存时,所有副本在任何时刻对外呈现的值必须一致。一旦某个副本被修改,其他副本必须及时同步,否则将出现脏读或过期数据。
核心定义: 对于任意内存位置 X,在任何时间点,所有缓存副本对 X 的读取操作必须返回最近一次写入操作的值(或该写入操作的后续一致状态)。
1.2 产生原因分析
缓存一致性问题主要源于两个场景:多核共享内存与分布式节点复制。下表对比了两者的根本差异:
| 场景 | 根本原因 | 典型架构 | 一致性粒度 |
|---|---|---|---|
| 多核 CPU | 每个核心拥有私有 L1/L2 缓存,写操作先到达本地缓存,其他核心不可见 | SMP / NUMA | 缓存行(Cache Line) |
| 分布式缓存 | 数据在多个节点间复制,网络延迟导致更新传播滞后 | Redis Cluster / Memcached | 键值对(Key-Value) |
1.3 多核场景下的写传播与串行化
多核缓存一致性需要解决两个子问题:
- 写传播(Write Propagation): 一个核心的写操作必须被其他核心感知。
- 写串行化(Write Serialization): 所有核心必须看到相同的写操作顺序。
下图展示了四核系统中,核心 0 修改变量 X 后,其他核心缓存行失效的典型流程:
1.4 分布式缓存中的一致性问题
在分布式系统中,缓存一致性面临更复杂的挑战:
- 网络分区: 节点间通信可能中断,导致更新无法传播。
- 副本延迟: 主从复制存在时间窗口,从节点可能返回旧数据。
- 并发写入: 多个客户端同时修改同一缓存键,产生冲突。
典型陷阱: 许多团队在分布式缓存中只关注“最终一致性”,却忽略了业务对“读己之写”的强一致性要求。例如用户修改个人信息后立即刷新页面,若缓存未同步,将看到旧数据,造成体验断裂。
1.5 CAP 理论在缓存中的体现
CAP 理论指出,分布式系统在一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)三者中最多同时满足两个。缓存系统作为分布式数据层,必须做出明确取舍:
| CAP 组合 | 缓存策略示例 | 典型场景 | 代价 |
|---|---|---|---|
| CP (一致 + 分区) | ZooKeeper 缓存、强一致缓存锁 | 分布式锁、配置中心 | 分区时不可用,牺牲可用性 |
| AP (可用 + 分区) | Redis 异步主从、CDN 缓存 | 商品详情页、新闻 feed | 可能返回过期数据,牺牲一致性 |
| CA (一致 + 可用) | 单机缓存、本地内存缓存 | 单体应用、嵌入式系统 | 无法容忍网络分区,分布式下不现实 |
下图展示了 CAP 三角在缓存设计中的决策路径:
1.6 一致性模型分类
根据 CAP 取舍,缓存一致性模型可细分为以下层次:
- 强一致性(Linearizability): 写操作完成后,任何后续读操作立即返回新值。实现代价高,通常需要分布式共识协议(如 Paxos/Raft)。
- 最终一致性(Eventual Consistency): 如果没有新写入,所有副本最终会收敛到相同值。DNS 缓存、CDN 是典型例子。
- 因果一致性(Causal Consistency): 有因果关系的操作必须按顺序被所有节点看到,无因果关系的操作可以并发。
- 读己之写(Read-Your-Writes): 客户端写入后,同一客户端后续读取一定能看到自己的写入。
实践建议: 在微服务缓存设计中,优先识别业务对一致性的真实需求。例如“库存扣减”必须强一致,而“用户头像”可以接受最终一致。不要为所有数据统一选择最高一致性级别,否则会无谓牺牲性能和可用性。