直写模式(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. 返回结果
- 发起写请求:应用程序将数据写入缓存层。
- 同步写入:缓存层接收到数据后,立即同步调用数据库更新接口。
- 双写确认:
- 如果数据库写入失败,整个操作回滚(或报错)。
- 如果数据库写入成功,缓存层随即更新内部数据。
- 返回结果:当且仅当数据库和缓存都更新完成后,才向应用层返回成功。
二、读操作 (配套模式)
由于 Write Through 确保了缓存中始终拥有与数据库一致的最新数据,因此它通常配合 直读模式 (Read Through) 使用。
在这种组合下:
- 读操作:直接从缓存读取,由于写操作保证了一致性,缓存命中率极高且无脏数据。
- 透明性:应用层完全感知不到数据库的存在。
关键考量:一致性保证与写入延迟
一、如何保证“双写”的一致性?
虽然 Write Through 在流程上要求双写,但在分布式系统中,保证两个独立系统的原子性是极具挑战的。常见的实现方案包括:
- 分布式事务 (TCC/2PC):
- 将数据库更新和缓存更新纳入同一个事务。
- 优点:强一致性。
- 缺点:性能损耗极大,通常不推荐在高性能缓存场景使用。
- 本地事务 + 重试机制:
- 在数据库事务中完成写入,若缓存更新失败,则将失败任务放入消息队列进行异步重试。
- 异常回滚:
- 先写数据库,若失败则直接返回错误;若数据库成功但缓存失败,则尝试通过“删除缓存”来确保最终一致性(转为类似 Cache Aside 的失效模式)。
二、写入延迟
这是该模式的主要代价。由于每次写入都必须等待数据库 IO 完成,其写入响应时间(Latency)取决于:
Cache 写入耗时 + DB 写入耗时。
相比 Cache Aside(先写库后删缓存),Write Through 的链路更长,在高并发写场景下可能会成为性能瓶颈。
适用场景
- 强一致性业务:如银行账户余额、库存系统等对数据准确性要求极高,不能容忍短暂不一致的场景。
- 读频率极高,写频率适中:因为写入时已经预热了缓存,后续读请求可以获得极致的性能(100% 缓存命中且无 Miss 后的回填开销)。
- 数据丢失零容忍:相比
Write Back,该模式不会因为缓存宕机而丢失尚未刷盘的数据。
总结
- 优点:数据一致性极高;简化应用层逻辑(只需对接缓存);读性能极佳。
- 缺点:写入延迟较高;对缓存系统的可靠性依赖极强(若缓存挂了,写操作也无法进行)。
- 适用场景:对数据一致性有硬性要求,且写压力在数据库承受范围内的核心业务系统。