Redis 多级缓存架构学习笔记

这份笔记涵盖:

  • 多级缓存的整体结构

  • 各层的作用(浏览器、本地缓存、Redis、JVM 缓存)

  • 请求的完整流向

  • 缓存更新与同步机制

  • Canal 的作用

  • 缓存一致性

  • 多级缓存优点与注意点


一、系统总体结构概述

根据架构图,系统采用 多级缓存体系 来提升接口性能、减少数据库压力、应对高并发。整体通路如下:

复制代码
浏览器缓存
 ↓
Nginx 反向代理(多个节点) → OpenResty 本地缓存
 ↓
Redis 分布式缓存
 ↓
Tomcat(多个节点)JVM 进程缓存
 ↓
数据库
 ↑
Canal(监听数据库更新并同步缓存)

这里包含:

  1. 客户端缓存(浏览器缓存)

  2. Nginx 层本地缓存(OpenResty)

  3. Redis 缓存层(分布式缓存)

  4. JVM 进程内缓存(应用服务器本地缓存)

  5. 数据库(最终一致性)

  6. 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 缓存即可:

  1. Canal 监听 binlog

  2. Canal 触发缓存删除事件

  3. 删除 Redis key

  4. OpenResty 一级缓存失效

  5. JVM 缓存 TTL 到期自然清理

最终实现:

  • 一致性维持

  • 老数据不会长期存在


五、缓存一致性策略

多级缓存天生会存在不一致问题,因此系统采用:

  1. Redis 主动删除(强一致性保障)

  2. Nginx/OpenResty 本地缓存设置较短 TTL

  3. JVM 进程缓存 TTL 更短(几十秒 ~ 几分钟)

  4. 写操作后主动删除 Redis 缓存(Cache Aside)

整体保证系统在短时间内达到最终一致性。


六、采用多级缓存的优势

  1. 最高性能:OpenResty 缓存 + JVM 进程缓存

  2. 高可用:Redis 作为中心缓存

  3. 高扩展性:Nginx 与 Tomcat 都是多实例

  4. 天然抗高并发:多层挡住大量请求

  5. 容错能力强:Redis 宕机也能靠 L1/L3 临时顶住


七、总结(结合图片结构)

根据图中架构,多级缓存三层分别扮演了:

层级 名称 描述 目标
L1 OpenResty 本地缓存 最前端、本地内存缓存 拦截 70% 以上请求
L2 Redis 分布式缓存 全局共享缓存 服务集群一致的热点数据
L3 JVM 进程缓存 应用内部缓存 减少 Redis 压力、提高性能

Canal:

  • 负责数据更新后的缓存同步

  • 避免缓存脏读

  • 维持最终一致性

这也正是黑马程序员课程中重点讲解的 多级缓存架构方案

相关推荐
一起学开源1 小时前
分布式基石:CAP定理与ACID的取舍艺术
分布式·微服务·架构·流程图·软件工程
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(一)Geaflow-Infer 模块简介
架构
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(三)环境初始化流程
架构
语落心生2 小时前
Apache Geaflow推理框架Geaflow-infer 解析系列(二)整体架构设计
架构
鹏北海3 小时前
多标签页登录状态同步:一个简单而有效的解决方案
前端·面试·架构
Xの哲學4 小时前
Linux 分区表深度技术剖析
linux·网络·算法·架构·边缘计算
q***18844 小时前
Ubuntu上安装、使用Redis的详细教程
redis·ubuntu·bootstrap
TracyCoder1235 小时前
微服务概念理解学习笔记
学习·微服务·架构
q***65695 小时前
Windows环境下安装Redis并设置Redis开机自启
数据库·windows·redis