Redis-缓存(缓存穿透、缓存雪崩、缓存击穿)(带解决方案流程图)

91 阅读4分钟

缓存核心知识笔记

一、什么是缓存

缓存是临时存储高频访问数据的技术,将数据存于读取更快的介质(如内存),核心作用是降低后端服务 / 数据库压力、提升请求响应速度

二、添加 Redis 缓存

Redis 是主流分布式缓存中间件,接入流程:

  1. 请求优先查询 Redis;
  2. 缓存命中→直接返回结果;
  3. 缓存未命中→查询数据库,将结果写入 Redis 后返回。

三、缓存更新策略

根据业务场景选择:

  • Cache Aside(旁路缓存)

    • 读→先查缓存,无则查库 + 写缓存;

    • 写→先更数据库,再删缓存。

  • Write Through(写穿透) :写操作同时更新缓存和数据库,强一致但写性能略低

  • Write Back(写回) :写操作先更缓存,异步刷回数据库,性能高但可能丢数据

四、缓存常见问题

问题定义简要解决方案
缓存穿透请求不存在的数据,缓存 / 数据库均无结果缓存空值、布隆过滤器
缓存雪崩大量缓存同时失效,请求全打向数据库过期时间加随机值、多级缓存、Redis 集群
缓存击穿热点 key 突然失效,请求瞬间压垮数据库热点 key 永不过期、逻辑过期、分布式锁

五、缓存问题解决方案(详细说明 + 流程图)

1. 缓存穿透解决方案

(1)缓存空值(优化:命中时判断空值有效性)
  • 操作:数据库查询无结果时,写入 “空值” 到 Redis 并设短过期时间(5 分钟);请求命中缓存后,先判断是否为有效数据,空值则直接返回无结果。
  • 效果:阻断同个无效请求重复访问数据库,避免穿透。
  • 流程图:

image.png

(2)布隆过滤器
  • 操作:提前将数据库所有存在的 key 存入布隆过滤器;请求先过过滤器,判 “不存在” 直接返回;缓存命中后需校验是否为空值,空值则返回无结果。
  • 注意:存在 “假阳性”(误判存在),需搭配缓存空值兜底。
  • 流程图:

image.png

2. 缓存雪崩解决方案

(1)过期时间加随机值
  • 操作:缓存过期时间 = 基础时间 + 随机数(0~300 秒),分散过期节点。
(2)多级缓存
  • 操作:本地缓存(如 Guava Cache)+ 分布式缓存(Redis),请求按 “本地→Redis→数据库” 顺序查询。
  • 效果:Redis 集群失效时,本地缓存拦截部分请求,降低数据库峰值压力。
(3)Redis 集群(高可用兜底)
  • 操作:部署主从 + 哨兵 / Redis Cluster 架构,避免单节点故障导致缓存全失效。
  • 效果:提升缓存服务可用性,减少宕机引发的雪崩。

3. 缓存击穿解决方案

(1)热点 key 永不过期
  • 操作:热点 key 不设 Redis 过期时间,通过后台异步线程定期(10 分钟 / 次)查询数据库并更新缓存。
  • 效果:彻底避免热点 key 过期引发的请求突增。
(2)逻辑过期(优化:未命中加锁 + 二次查缓存 + 异步更新)
  • 操作:缓存值附加逻辑过期字段(非 Redis 自身过期);

    • 未命中:先抢分布式锁,获锁后二次查缓存(避免重复查库),未命中则查库写缓存,释放锁后返回;获锁失败则重试;
    • 已过期:抢分布式锁,获锁后立即返回旧值,同时异步线程查库更新缓存 + 释放锁;未获锁直接返回旧值。
  • 效果:无请求阻塞,兼顾响应速度与并发安全,避免重复查库。

  • 流程图:

image.png

(3)分布式锁(优化:未命中加锁 + 二次查缓存)
  • 操作:缓存未命中时抢 Redis 分布式锁,获锁后二次查询缓存(避免重复查库);

    • 二次命中则直接释放锁返回;
    • 二次未命中则查库,有数据则写缓存,无数据则标记空值,最终释放锁返回;
    • 获锁失败则等待后重试查缓存。
  • 效果:严格控制查库线程数量,通过二次查缓存进一步降低数据库压力,避免击穿。

  • 流程图:

image.png

六、缓存工具封装

将缓存操作封装为通用工具类,统一处理:

  • 连接池管理:复用 Redis 连接,减少连接开销;
  • 序列化:实现数据与缓存的 JSON/Protobuf 格式转换;
  • 异常降级:缓存不可用时,直接走数据库兜底;
  • 监控埋点:统计缓存命中率、耗时等指标。