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。
1.4 缓存击穿
定义:一个热点 key 在缓存过期失效的瞬间,大量并发请求同时涌入,全部穿透到数据库。
与穿透的区别:击穿针对的是“存在但刚好过期”的热点 key;穿透针对的是“根本不存在”的 key。
常见解决方案
- 互斥锁(Mutex):缓存失效后,只允许一个线程去数据库加载数据,其他线程等待或重试。
- 逻辑过期:缓存中不设置 TTL,而是存储一个逻辑过期时间字段,异步线程发现过期后主动更新。
- 热点数据永不过期:对极高热度的 key 不设置过期时间,通过后台任务定期刷新。
1.5 缓存雪崩
定义:大量缓存 key 在同一时间集中过期失效,或者缓存节点整体宕机,导致所有请求全部涌入数据库。
危害等级:雪崩是三种缓存异常中破坏力最大的,可能导致数据库瞬间被击穿,引发级联故障。
常见解决方案
| 策略 | 实现方式 | 适用场景 |
|---|---|---|
| 过期时间随机化 | 在基础 TTL 上增加随机偏移量(如 ±30%) | 批量缓存预热、定时任务场景 |
| 多级缓存 | 本地缓存(Caffeine)+ 分布式缓存(Redis)组合 | 高可用要求严格的业务 |
| 缓存高可用 | Redis 主从 + Sentinel 哨兵 / Redis Cluster 集群 | 防止节点宕机导致雪崩 |
| 限流降级 | 对数据库访问做限流,缓存失效时返回降级数据 | 大促、秒杀等流量洪峰场景 |
| 提前预热 | 系统上线前预先加载热点数据到缓存 | 定时任务、活动开始前 |
三种异常对比总结
| 异常类型 | 触发条件 | 影响范围 | 核心应对策略 |
|---|---|---|---|
| 缓存穿透 | 查询不存在的数据 | 单个 key 持续攻击 | 布隆过滤器、缓存空对象 |
| 缓存击穿 | 热点 key 刚好过期 + 高并发 | 单个热点 key | 互斥锁、逻辑过期、永不过期 |
| 缓存雪崩 | 大量 key 同时过期 / 节点宕机 | 全局性影响 | 过期随机化、多级缓存、高可用、限流 |
实战建议:生产环境中三种异常可能同时发生。建议在架构设计阶段就将“防穿透、防击穿、防雪崩”作为缓存层的标配能力,而非事后补救。