1. 缓存基础概念

1.1 什么是缓存

缓存(Cache)是计算机系统中一种用于临时存储数据副本的高速存储层。当系统需要读取数据时,会优先从缓存中获取,只有在缓存未命中时才会访问速度较慢的后端存储(如数据库、磁盘)。

在 Redis 场景下,缓存通常指将热点数据存储在内存中,利用内存的纳秒级读写速度,大幅降低数据访问延迟。

核心特征:缓存是“空间换时间”策略的典型实现——用额外的内存空间换取更快的访问速度。

1.2 缓存的作用

作用维度 具体说明 典型效果
加速读写 内存读取速度远快于磁盘 I/O,缓存命中时响应时间从毫秒级降至微秒级 读延迟降低 10~100 倍
保护后端 缓存吸收大量读请求,减少数据库连接数和查询压力 数据库 QPS 降低 60%~90%
削峰填谷 应对突发流量,缓存层缓冲瞬时高并发请求,防止后端过载 系统可用性提升至 99.9%+
扩展读能力 通过 Redis 读写分离架构,横向扩展缓存节点提升整体吞吐 读吞吐量线性扩展

1.3 缓存穿透

定义:查询一个根本不存在的数据,缓存层和数据库层都没有命中,每次请求都直接打到数据库。

危害:攻击者可以利用不存在的 key 发起大量请求,导致数据库压力骤增,甚至引发宕机。

常见解决方案

  • 缓存空对象:对查询结果为 null 的 key 也缓存一个短生命周期的空值(如 60s),避免重复穿透。
  • 布隆过滤器:在缓存层之前加一层布隆过滤器,快速判断 key 是否可能存在,过滤掉 100% 不存在的查询。
  • 参数校验:在业务入口对请求参数做合法性校验,拦截明显无效的 key。
缓存穿透流程示意图 客户端 Redis 缓存 MySQL 数据库 攻击者 查询不存在的 key 缓存未命中,穿透到 DB 大量不存在 key 请求 穿透后果 • 缓存层无数据 • 数据库直接承压 • 连接池耗尽 • 系统响应变慢 • 严重时宕机

1.4 缓存击穿

定义:一个热点 key 在缓存过期失效的瞬间,大量并发请求同时涌入,全部穿透到数据库。

与穿透的区别:击穿针对的是“存在但刚好过期”的热点 key;穿透针对的是“根本不存在”的 key。

常见解决方案

  • 互斥锁(Mutex):缓存失效后,只允许一个线程去数据库加载数据,其他线程等待或重试。
  • 逻辑过期:缓存中不设置 TTL,而是存储一个逻辑过期时间字段,异步线程发现过期后主动更新。
  • 热点数据永不过期:对极高热度的 key 不设置过期时间,通过后台任务定期刷新。
缓存击穿流程示意图 请求 1 请求 2 请求 N Redis 缓存 热点 key 已过期 MySQL 数据库 瞬间高并发冲击 击穿条件 ① 单个热点 key ② 缓存刚好过期 ③ 大量并发请求 ④ 同时穿透到 DB

1.5 缓存雪崩

定义:大量缓存 key 在同一时间集中过期失效,或者缓存节点整体宕机,导致所有请求全部涌入数据库。

危害等级:雪崩是三种缓存异常中破坏力最大的,可能导致数据库瞬间被击穿,引发级联故障。

常见解决方案

策略 实现方式 适用场景
过期时间随机化 在基础 TTL 上增加随机偏移量(如 ±30%) 批量缓存预热、定时任务场景
多级缓存 本地缓存(Caffeine)+ 分布式缓存(Redis)组合 高可用要求严格的业务
缓存高可用 Redis 主从 + Sentinel 哨兵 / Redis Cluster 集群 防止节点宕机导致雪崩
限流降级 对数据库访问做限流,缓存失效时返回降级数据 大促、秒杀等流量洪峰场景
提前预热 系统上线前预先加载热点数据到缓存 定时任务、活动开始前
缓存雪崩流程示意图 海量请求 Redis 缓存 大量 key 同时过期 MySQL 数据库 请求洪峰击穿 雪崩原因 • 大量 key 设置相同过期时间 • 缓存节点宕机 • 网络分区导致缓存不可用 解决方案 • 过期时间加随机偏移 • 多级缓存架构 • 限流 + 降级 + 预热

三种异常对比总结

异常类型 触发条件 影响范围 核心应对策略
缓存穿透 查询不存在的数据 单个 key 持续攻击 布隆过滤器、缓存空对象
缓存击穿 热点 key 刚好过期 + 高并发 单个热点 key 互斥锁、逻辑过期、永不过期
缓存雪崩 大量 key 同时过期 / 节点宕机 全局性影响 过期随机化、多级缓存、高可用、限流
实战建议:生产环境中三种异常可能同时发生。建议在架构设计阶段就将“防穿透、防击穿、防雪崩”作为缓存层的标配能力,而非事后补救。