第2章 多级缓存整体架构图:逻辑分层、各层职责、数据流向总览
多级缓存架构的核心思想是通过在请求链上不同位置部署缓存层,逐级缓存热数据,从而将最频繁的访问尽可能在离客户端最近、延迟最低的层级命中。本章从全局视角构建完整的逻辑分层关系,明确每一层的边界与职责,并梳理请求数据在主链路与控制链路上的流动路径,为后续章节的深度设计奠定基础。
本章核心视图:下图展示了标准多级缓存架构的 5 层结构(CDN → 反向代理 → 进程内本地缓存 → 分布式缓存 → 数据库),其中蓝色节点代表缓存层,绿色节点代表数据源,箭头表示请求流动方向。注意信任链路与回源链路的分离。
2.1 系统边界与分层定义
多级缓存系统并非孤立存在,它处于「客户端」与「持久化数据源」之间。每一层都有明确的物理或逻辑边界:
- 客户端边界:用户设备 / 浏览器 / 移动端 → 第一级缓存(CDN 或反向代理)。跨越此边界的请求通常携带身份认证或会话信息。
- 缓存层内部边界:进程内缓存仅同进程可见;分布式缓存跨节点共享但存在网络分区。
- 数据源边界:最底层与数据库之间必须保证最终一致性,不允许脏数据无限制扩散。
⚠ 关键风险:信任链路假设每一层对上游的返回数据“盲目信任”。若中间层被篡改(如缓存投毒),下游无法自检。必须在网关层做数据签名或完整性校验。
2.2 各层职责与性能对比
| 层级 | 典型技术 | 存储位置 | 访问延迟 | 容量范围 | 命中率特征 |
|---|---|---|---|---|---|
| CDN / 边缘 | CloudFront, Akamai, Varnish | 全球边缘节点 | 10~50ms | TB 级 | 静态资源 >90% |
| 反向代理 / 网关 | Nginx, HAProxy, OpenResty | 服务器本地文件 | 1~5ms | GB 级 | 动态聚合 >70% |
| 进程内本地缓存 | Caffeine, Guava, EHcache | JVM 堆内 | 0.01~0.1ms | MB~GB | 热点数据 >95% |
| 分布式缓存 | Redis Cluster, Memcached | 独立内存集群 | 1~3ms | GB~TB | 共享热点 60~85% |
| 数据库 | MySQL, PostgreSQL, TiDB | 磁盘 + buffer pool | 10~100ms | TB~PB | 回源命中 ≈100% |
2.3 数据流与控制流总览
2.3.1 正常请求数据流
一次读请求的完整路径(Cache-Aside 模式):
- 请求到达 CDN 节点,若命中且未过期,直接返回静态内容,链路结束。
- CDN 未命中 → 回源到反向代理(网关),检查 Nginx 缓存(如 proxy_cache)。
- 反向代理未命中 → 透传到应用服务器,优先查询进程内本地缓存(如 Caffeine)。
- 本地缓存未命中 → 使用 分布式缓存(Redis)查找。
- 分布式缓存也未命中 → 查询数据库,并将结果按 TTL 逐级回填。
性能指标参考:经典型业务场景下,仅靠本地缓存即可过滤 90% 以上重复查询,加上分布式缓存后整体命中率可达 99%,数据库仅承担 1% 的请求。
2.3.2 控制流与信任链路
- 失效传播:当数据库发生写操作时,必须发送失效事件(如 Redis PUB/SUB 或消息队列)到下游缓存层,避免读到旧数据。
- 回填决策:各缓存层独立决定是否缓存、缓存多久,且上级缓存不可向下级缓存写入数据——数据永远“向下流”,失效通知向上流。
- 信任契约:同一层内的节点间信任(如 Redis 主从同步使用 TCP 长连接),跨层信任依赖于签名或校验和,尤其对不可信的外部网络缓存。
2.4 选型权衡与风险点
| 权衡维度 | 选项A | 选项B | 建议场景 |
|---|---|---|---|
| 缓存粒度 | 对象级(小) | 页面级(大) | 动态服务 → 对象级;静态资源 → 页面级 |
| 失效策略 | TTL 被动过期 | 主动失效 + 消息 | 一致性要求低 → TTL;要求高 → 主动失效 |
| 本地 vs 分布式 | 本地更快但孤岛 | 分布式共享但延迟高 | 高频热点数据 → 本地兜底;共享状态 → 分布式 |
典型风险清单:
• 缓存穿透:请求直穿所有缓存打到数据库 → 解决:布隆过滤器 + 空值缓存。
• 缓存雪崩:大量缓存同时过期 → 解决:TTL 随机化、本地预热。
• 数据不一致:写后未及时删除缓存 → 解决:延迟双删 + binlog 订阅。
• 资源竞争:本地缓存占用过多堆内存 → 解决:限制 maxSize + 软引用/弱引用。
• 缓存穿透:请求直穿所有缓存打到数据库 → 解决:布隆过滤器 + 空值缓存。
• 缓存雪崩:大量缓存同时过期 → 解决:TTL 随机化、本地预热。
• 数据不一致:写后未及时删除缓存 → 解决:延迟双删 + binlog 订阅。
• 资源竞争:本地缓存占用过多堆内存 → 解决:限制 maxSize + 软引用/弱引用。
2.5 落地步骤与验收标准
落地步骤
- 第一步:梳理业务数据热力分布,识别“读多写少”的 Key。
- 第二步:先从数据库 → 分布式缓存(Redis)一层引入,观测效果。
- 第三步:在应用进程内添加本地缓存(Caffeine),配合
@Cacheable注解或手动 get/put。 - 第四步:根据静态资源比例,配置反向代理缓存(Nginx proxy_cache)和 CDN。
- 第五步:搭建失效通知链路(MQ + Redis SUB),测试一致性。
- 第六步:全链路压测,调优各级 TTL 与容量。
验收标准
- 全链路 TP99 延迟降低 60% 以上(对比无缓存基线)。
- 数据库 QPS 下降 80%,异常波动时不超过警戒线。
- 缓存命中率稳定在 95%+(监控面板可观测每层命中率)。
- 写操作后,缓存与数据库一致时间 ≤ 200ms(最终一致性窗口)。
- 单机本地缓存 OOM 风险为零(设置
maximumSize+ 逐出策略)。
💡 建议:在生产环境部署多级缓存前,先利用流量回放工具(如 GoReplay)在预发环境模拟真实流量,验证各层缓存策略的协同效果,避免直接上线带来雪崩风险。