深入解析:Redis 多级缓存架构学习笔记

这份笔记涵盖:
多级缓存的整体结构
各层的作用(浏览器、本地缓存、Redis、JVM 缓存)
请求的完整流向
缓存更新与同步机制
Canal 的作用
缓存一致性
多级缓存优点与注意点
一、系统总体结构概述
根据架构图,系统采用 多级缓存体系 来提升接口性能、减少数据库压力、应对高并发。整体通路如下:
浏览器缓存
↓
Nginx 反向代理(多个节点) → OpenResty 本地缓存
↓
Redis 分布式缓存
↓
Tomcat(多个节点)JVM 进程缓存
↓
数据库
↑
Canal(监听数据库更新并同步缓存)
这里包含:
客户端缓存(浏览器缓存)
Nginx 层本地缓存(OpenResty)
Redis 缓存层(分布式缓存)
JVM 进程内缓存(应用服务器本地缓存)
数据库(最终一致性)
Canal(缓存更新同步组件)
二、缓存分层结构详解
1. 浏览器端缓存(客户端缓存)
特点:
由前端配置 Cache-Control 产生
直接存储 HTML、JS、CSS 或静态 JSON
减少请求进入服务器
适用:
静态页面(如 item.html)
不经常变化的资源
2. Nginx → OpenResty 本地缓存(一级缓存)
架构图中 Nginx 上挂了多个 OpenResty 实例(8081、8082、8083),它们提供:
本地 L1 缓存(Lua Shared Dict)
复杂缓存逻辑控制(比原生 proxy_cache 更灵活)
工作机制(一级缓存)
请求到达 OpenResty
→ 查本地共享字典缓存
→ 命中:直接返回
→ 未命中:查 Redis
优点:
在 Nginx 层拦截大量请求
减轻后端压力
不需要经过 Java 服务即可返回数据
延迟极低
缓存对象:
商品详情页数据
首页热点数据
店铺信息
这是图片中绿色区域 “本地缓存” 所表达的部分。
3. Redis 缓存(二级缓存)
OpenResty 未命中缓存后会访问 Redis:
OpenResty → Redis
这是系统的中心缓存层:
全局共享
持久存在于内存中
QPS 高
可配置过期时间、热点数据保护
职责:
缓存大量热点数据
给一级缓存回填数据
向应用服务器提供共享缓存
适用:
商品、店铺、分类等基础信息
分布式业务数据缓存
4. JVM 进程缓存(三级缓存)
架构图右侧黄色的 Tomcat 集群(8081、8082)代表 Java 服务节点,每个节点内部都会维护一个:
进程内缓存(如 Caffeine)
三级缓存属于:
应用级本地缓存
用途:
加速 Redis 命中后的数据处理,例如反序列化
减少 Redis 调用次数
缓解网络压力和序列化开销
特点:
仅当前 JVM 节点可用
不共享,需要 TTL 维持一致性
命中速度最快(纳秒级)
三级缓存是 Redis 未命中后最后一层“缓存兜底层”。
5. 数据库(最终数据源)
当 JVM 缓存仍未命中:
Tomcat → DB
从数据库读取最新数据,并负责:
回写 Redis
通过 Canal 的监听实现缓存更新
6. Canal(数据变更监听)
图中 Canal 位于 DB 与缓存层之间,用于:
监听 MySQL binlog
捕获数据库更新、插入、删除
通知 Redis/JVM/Nginx 缓存更新
保证缓存一致性
这是保证多级缓存数据准确性的关键组件。
三、请求全链路流程解析(结合图片)
以请求 /item/10001 为例:
浏览器 → Nginx → OpenResty → Redis → JVM Cache → DB
步骤 1:浏览器缓存
若 item.html 已缓存 → 直接命中,不进入服务器。
步骤 2:Nginx 反向代理
浏览器未命中 → 将请求发送到 OpenResty。
Nginx 内部 upstream 采用 URI Hash 实现负载均衡(图中配置):
upstream nginx-cluster {
hash $request_uri;
}
保证相同商品请求分到同一个 OpenResty 节点,提高本地缓存命中率。
步骤 3:OpenResty 本地缓存(一级)
OpenResty 查共享字典:
local_cache:get("item:10001")
命中 → 直接返回。
未命中 → 查 Redis。
步骤 4:Redis 二级缓存
若 Redis 命中:
返回数据给 OpenResty
OpenResty 回填一级缓存
返回给客户端
若 Redis 未命中:
请求后端 Tomcat(负载均衡)
Tomcat 查 JVM 本地缓存(三级)
JVM 仍未命中 → 查 DB
回写 Redis
回写 OpenResty
返回给客户端
四、数据更新流程(结合 Canal)
当数据在 DB 中被更新时,缓存必须同步更新。
流程如下:
DB → binlog → Canal → 通知缓存系统 → 删除 Redis 缓存 → L1 缓存自然过期
Canal 不直接操作 OpenResty,只需要删除 Redis 缓存即可:
Canal 监听 binlog
Canal 触发缓存删除事件
删除 Redis key
OpenResty 一级缓存失效
JVM 缓存 TTL 到期自然清理
最终实现:
一致性维持
老数据不会长期存在
五、缓存一致性策略
多级缓存天生会存在不一致问题,因此系统采用:
Redis 主动删除(强一致性保障)
Nginx/OpenResty 本地缓存设置较短 TTL
JVM 进程缓存 TTL 更短(几十秒 ~ 几分钟)
写操作后主动删除 Redis 缓存(Cache Aside)
整体保证系统在短时间内达到最终一致性。
六、采用多级缓存的优势
最高性能:OpenResty 缓存 + JVM 进程缓存
高可用:Redis 作为中心缓存
高扩展性:Nginx 与 Tomcat 都是多实例
天然抗高并发:多层挡住大量请求
容错能力强:Redis 宕机也能靠 L1/L3 临时顶住
七、总结(结合图片结构)
根据图中架构,多级缓存三层分别扮演了:
| 层级 | 名称 | 描述 | 目标 |
|---|---|---|---|
| L1 | OpenResty 本地缓存 | 最前端、本地内存缓存 | 拦截 70% 以上请求 |
| L2 | Redis 分布式缓存 | 全局共享缓存 | 服务集群一致的热点数据 |
| L3 | JVM 进程缓存 | 应用内部缓存 | 减少 Redis 压力、提高性能 |
Canal:
负责数据更新后的缓存同步
避免缓存脏读
维持最终一致性
这也正是黑马程序员课程中重点讲解的 多级缓存架构方案。
浙公网安备 33010602011771号