4. 缓存一致性协议:Cache Aside、Read/Write Through、Write Behind Caching 原理与适用场景

在分布式缓存系统中,缓存与数据库之间的数据一致性是核心治理难题。不同的缓存一致性协议定义了应用程序如何与缓存及底层存储交互,直接影响系统的吞吐量、延迟与数据一致性保证。本章深入剖析三种主流协议:Cache Aside、Read/Write Through 与 Write Behind Caching,并给出明确的选型建议。

4.1 Cache Aside 旁路缓存

Cache Aside 是最常用的缓存策略,应用程序直接同时操作缓存和数据库。其核心原则是:读时回填,写时失效。

4.1.1 读流程

  1. 应用先查询缓存。
  2. 缓存命中,直接返回数据。
  3. 缓存未命中,查询数据库。
  4. 将查询结果写入缓存,并设置过期时间。
  5. 返回数据给调用方。

4.1.2 写流程

  1. 应用更新数据库。
  2. 使缓存中的对应键失效(删除或标记过期)。
关键陷阱:写操作必须先更新数据库,再删除缓存。若先删除缓存再更新数据库,在并发场景下会导致缓存中写入旧数据,造成长期不一致。
适用场景:读多写少、对一致性要求较高、可接受短暂缓存未命中的业务。例如用户信息、商品详情、配置数据。
Cache Aside 旁路缓存读写流程 应用 缓存 数据库 读流程 ① 读缓存 未命中 ② 查数据库 ③ 回填缓存 ④ 返回数据 写流程 ① 更新数据库 ② 删除缓存 核心原则 • 读:缓存未命中 → 查数据库 → 回填缓存 → 返回 • 写:更新数据库 → 删除缓存(先库后删,避免并发脏读)

4.2 Read/Write Through 读写穿透

Read/Write Through 将缓存抽象为数据访问的唯一入口。应用程序只与缓存交互,缓存负责与数据库同步数据。这种模式对应用层更友好,但缓存层承担了更多职责。

4.2.1 Read Through

  • 应用请求数据时,直接访问缓存。
  • 缓存命中则直接返回。
  • 缓存未命中时,缓存组件自动从数据库加载数据,写入自身,再返回给应用。
  • 应用无需感知数据库的存在。

4.2.2 Write Through

  • 应用写入数据时,直接写入缓存。
  • 缓存同步将数据写入数据库。
  • 只有数据库写入成功,缓存才确认写入完成。
一致性保证:Write Through 在写入数据库成功之前不会返回成功,因此缓存与数据库始终强一致。代价是写入延迟增加,因为每次写操作都包含一次数据库同步写。
适用场景:对一致性要求极高、写入频率可控、可以接受写入延迟增加的系统。例如金融交易、订单状态、库存扣减。
Read/Write Through 读写穿透架构 应用 缓存(代理层) 数据库 读流程 ① 读请求 未命中 ② 自动加载 ③ 回填缓存 ④ 返回数据 写流程 ① 写请求 ② 同步写入 DB ③ 确认写入 ④ 返回成功 特点:应用只与缓存交互,缓存层封装了数据库读写逻辑,实现解耦。

4.3 Write Behind Caching 异步回写

Write Behind Caching(又称 Write Back)与 Write Through 类似,应用只与缓存交互。但区别在于:写入缓存后立即返回成功,数据库的更新被异步批量执行。缓存层会合并、延迟写入数据库。

4.3.1 核心流程

  1. 应用写入数据到缓存,缓存立即返回成功。
  2. 缓存将写操作记录到内部队列或日志。
  3. 后台线程或定时任务批量将数据刷新到数据库。
  4. 若缓存宕机,未刷入数据库的数据可能丢失。

4.3.2 关键权衡

维度 Write Behind Write Through
写入延迟 极低(仅缓存写) 较高(等待数据库)
数据库压力 低(批量合并写入) 高(每次写都落盘)
数据一致性 最终一致性,有丢失风险 强一致性
实现复杂度 高(需队列、重试、幂等) 中等
风险提示:Write Behind 在缓存节点宕机或网络分区时,未刷入数据库的写入数据会永久丢失。必须配合持久化队列(如 Kafka、WAL)和故障恢复机制使用。
适用场景:写吞吐量极高、对一致性要求不苛刻、可接受数据短暂丢失的业务。例如用户行为日志、点赞计数、访问统计、社交 Feed 流。

4.4 三种协议对比总结

协议 读一致性 写一致性 写入延迟 数据库压力 实现复杂度 典型场景
Cache Aside 最终一致(有窗口期) 最终一致(先库后删) 低 中 低 用户信息、商品详情
Read/Write Through 强一致 强一致 高 高 中 金融交易、订单状态
Write Behind 最终一致 最终一致(有丢失风险) 极低 低(批量) 高 日志、计数、Feed 流

4.5 选型决策建议

  • 业务一致性要求极高(如支付、库存):优先选择 Read/Write Through,或 Cache Aside 配合分布式锁与版本号。
  • 读多写少、允许短暂不一致(如商品展示):Cache Aside 是最简单高效的选择。
  • 写吞吐量巨大、可接受最终一致(如日志收集):Write Behind 能大幅降低数据库写入压力。
  • 混合使用:实际系统中常将三种协议组合。例如核心交易用 Write Through,非核心统计用 Write Behind。
治理契约视角:在分布式缓存一致性治理中,协议选择决定了后续的契约测试策略。Cache Aside 需重点测试缓存失效与回填的并发时序;Write Through 需验证缓存代理层的同步写入逻辑;Write Behind 则必须覆盖异步队列的持久化、重试与幂等性契约。