3、多级缓存架构总览:本地缓存(L1)、分布式缓存(L2)、数据库直读(L3)的分层设计原则

在数据库缓存一致性体系中,多级缓存架构是平衡性能、一致性与成本的核心手段。本章将系统阐述本地缓存(L1)、分布式缓存(L2)与数据库直读(L3)三层结构的设计原则、职责边界与协作机制。

3.1 三层缓存的分层定位与职责

每一层缓存都针对不同的访问特征与一致性要求进行设计,形成从极速到可靠的阶梯式数据访问路径。

层级 存储位置 访问延迟 容量 一致性强度 典型场景
L1 本地缓存 应用进程内(堆内存) < 1ms MB ~ GB 弱(最终一致) 热点数据、不变配置、用户会话
L2 分布式缓存 独立缓存集群(如 Redis) 1 ~ 5ms GB ~ TB 中等(TTL + 主动失效) 共享热点、跨服务数据、降级兜底
L3 数据库直读 数据库(MySQL、PostgreSQL) 5 ~ 50ms TB ~ PB 强(ACID) 写后即读、关键交易、数据校验
设计要点: L1 追求极致速度,L2 追求共享与扩展,L3 追求绝对可靠。三层之间通过“先查 L1 → 未命中查 L2 → 未命中查 L3”的串联路径协作,每一层都承担不同的降级与回源职责。

3.2 分层设计原则

3.2.1 L1 本地缓存:就近访问,极低延迟

  • 数据特征: 高频读取、低频更新、允许短暂不一致。
  • 存储选型: Caffeine、Guava Cache、Ehcache,支持自动过期与最大容量限制。
  • 失效策略: 基于 TTL 的被动失效 + 主动删除(如 MQ 广播失效消息)。
  • 容量控制: 必须设置最大条目数或最大内存,防止 OOM。

3.2.2 L2 分布式缓存:共享存储,水平扩展

  • 数据特征: 跨服务共享、中等更新频率、需要一定一致性保障。
  • 存储选型: Redis Cluster、Redis Sentinel、Memcached。
  • 失效策略: TTL + 主动删除 + 缓存穿透保护(布隆过滤器)。
  • 高可用: 主从复制 + 哨兵/集群模式,避免单点故障。

3.2.3 L3 数据库直读:强一致兜底,数据权威源

  • 数据特征: 写后立即需要一致、缓存未命中或缓存降级时的最终回源。
  • 访问策略: 直连数据库执行查询,可配合读写分离(从库读取)。
  • 保护机制: 限流、熔断、连接池管理,防止缓存雪崩压垮数据库。
  • 一致性保障: 数据库事务提供 ACID 保证,是数据一致性的最后防线。
常见误区: 不要试图让 L1 缓存强一致,这会导致应用内频繁同步,丧失本地缓存的速度优势。L1 应默认接受最终一致,L2 负责协调跨节点的一致性,L3 负责绝对正确。

3.3 多级缓存访问流程

下图展示了标准的三级缓存串联访问路径,以及每一层未命中时的回源策略。

多级缓存访问流程 多级缓存访问流程(L1 → L2 → L3) 客户端请求 L1 本地缓存(进程内) 命中返回 L2 分布式缓存(Redis) 命中返回 L3 数据库直读(MySQL) 回写 L2 + L1(缓存填充) 返回客户端

3.4 缓存填充与失效策略

多级缓存架构中,数据的填充与失效必须遵循严格的顺序与策略,以保证各层数据的一致性。

3.4.1 缓存填充(Cache-Aside 模式)

  1. 读路径: 应用先查 L1 → 未命中查 L2 → 未命中查 L3(数据库)→ 将结果依次回填 L2 和 L1。
  2. 写路径: 先更新数据库(L3),然后删除 L2 和 L1 中的对应缓存,保证后续读取能获取最新数据。

3.4.2 失效策略对比

策略 适用层级 一致性保障 实现复杂度 典型实现
TTL 过期 L1、L2 最终一致 低 设置固定过期时间
主动删除 L1、L2 强(配合写操作) 中 写后删除缓存键
MQ 广播失效 L1(多实例) 最终一致 高 发送失效消息到所有实例
版本号校验 L2、L3 强 高 缓存携带数据版本号,与数据库比对
最佳实践: 对于 L1 本地缓存,优先使用 TTL 过期 + 主动删除的组合策略。TTL 保证最终一致性,主动删除在写操作发生时立即清除旧数据,减少不一致窗口。对于 L2 分布式缓存,增加布隆过滤器防止缓存穿透,并设置合理的 TTL 作为兜底。

3.5 分层设计的核心权衡

多级缓存并非层级越多越好,每一层都引入额外的复杂度与维护成本。以下是在架构设计中必须权衡的关键维度:

  • 延迟 vs. 一致性: L1 延迟最低但一致性最弱,L3 延迟最高但一致性最强。业务场景决定数据应该停留在哪一层。
  • 容量 vs. 成本: L1 使用应用内存(免费但有限),L2 使用独立集群(成本随容量线性增长),L3 使用磁盘存储(成本最低但延迟最高)。
  • 复杂度 vs. 收益: 对于大部分读多写少的场景,L1 + L3 两层架构已足够。引入 L2 分布式缓存的主要收益在于跨服务共享与更大的缓存容量。
架构决策建议: 从 L1 + L3 两层架构开始,当出现以下情况时引入 L2:① 多个服务需要共享同一份热点数据;② L1 缓存命中率低于 80% 且数据库压力持续升高;③ 需要缓存降级时有一个独立的高可用缓存层作为兜底。

3.6 多级缓存架构总览图

下图从全局视角展示多级缓存架构中各层之间的协作关系、数据流向以及关键组件。

多级缓存架构总览 多级缓存架构总览:L1 / L2 / L3 协作 应用服务集群(多个实例) L1 本地缓存(Caffeine) L1 本地缓存(Caffeine) L1 本地缓存(Caffeine) L2 分布式缓存(Redis Cluster) L3 数据库直读(MySQL 主从) 数据流向:客户端 → L1 → L2 → L3 → 回填 L2 + L1 → 返回客户端

3.7 本章小结

  • L1 本地缓存 提供纳秒级访问,适合高频热点,但容量有限且一致性弱。
  • L2 分布式缓存 提供毫秒级共享访问,适合跨服务热点,支持水平扩展。
  • L3 数据库直读 提供强一致兜底,是数据权威源,必须做好保护。
  • 三层之间通过 Cache-Aside 模式 串联,写操作先更新数据库再删除缓存,读操作逐层回源并回填。
  • 架构设计应从简单开始,根据实际瓶颈逐步引入更多层级,避免过度设计。