直写模式(Write Through Pattern) 是一种追求“数据强一致性”的缓存更新模式。在这一模式下,缓存不再仅仅是数据的加速副本,而是作为数据写入的唯一入口(或代理)。

其核心思想是:写操作必须同步经过缓存并写入数据库,只有两者都成功,写操作才算完成。


核心操作流程

一、写操作 (Write Path)

sequenceDiagram
    participant App as 应用程序
    participant Cache as 缓存
    participant DB as 数据库

    App->>Cache: 1. 发起写请求
    Cache->>DB: 2. 同步写入数据库
    DB-->>Cache: 3. 写入成功
    Cache->>Cache: 4. 更新/回填缓存
    Cache-->>App: 5. 返回结果
  1. 发起写请求:应用程序将数据写入缓存层。
  2. 同步写入:缓存层接收到数据后,立即同步调用数据库更新接口。
  3. 双写确认
    • 如果数据库写入失败,整个操作回滚(或报错)。
    • 如果数据库写入成功,缓存层随即更新内部数据。
  4. 返回结果:当且仅当数据库和缓存都更新完成后,才向应用层返回成功。

二、读操作 (配套模式)

由于 Write Through 确保了缓存中始终拥有与数据库一致的最新数据,因此它通常配合 直读模式 (Read Through) 使用。

在这种组合下:

  • 读操作:直接从缓存读取,由于写操作保证了一致性,缓存命中率极高且无脏数据。
  • 透明性:应用层完全感知不到数据库的存在。

关键考量:一致性保证与写入延迟

一、如何保证“双写”的一致性?

虽然 Write Through 在流程上要求双写,但在分布式系统中,保证两个独立系统的原子性是极具挑战的。常见的实现方案包括:

  1. 分布式事务 (TCC/2PC)
    • 将数据库更新和缓存更新纳入同一个事务。
    • 优点:强一致性。
    • 缺点:性能损耗极大,通常不推荐在高性能缓存场景使用。
  2. 本地事务 + 重试机制
    • 在数据库事务中完成写入,若缓存更新失败,则将失败任务放入消息队列进行异步重试。
  3. 异常回滚
    • 先写数据库,若失败则直接返回错误;若数据库成功但缓存失败,则尝试通过“删除缓存”来确保最终一致性(转为类似 Cache Aside 的失效模式)。

二、写入延迟

这是该模式的主要代价。由于每次写入都必须等待数据库 IO 完成,其写入响应时间(Latency)取决于: Cache 写入耗时 + DB 写入耗时。 相比 Cache Aside(先写库后删缓存),Write Through 的链路更长,在高并发写场景下可能会成为性能瓶颈。


适用场景

  1. 强一致性业务:如银行账户余额、库存系统等对数据准确性要求极高,不能容忍短暂不一致的场景。
  2. 读频率极高,写频率适中:因为写入时已经预热了缓存,后续读请求可以获得极致的性能(100% 缓存命中且无 Miss 后的回填开销)。
  3. 数据丢失零容忍:相比 Write Back,该模式不会因为缓存宕机而丢失尚未刷盘的数据。

总结

  • 优点:数据一致性极高;简化应用层逻辑(只需对接缓存);读性能极佳。
  • 缺点:写入延迟较高;对缓存系统的可靠性依赖极强(若缓存挂了,写操作也无法进行)。
  • 适用场景:对数据一致性有硬性要求,且写压力在数据库承受范围内的核心业务系统。