八、redis 入门 之 雪崩、穿透、击穿
一、击穿(单key)
1、描述
- 问题定义:某个 “高频访问的热点 Key”(如热门商品、首页 Banner)突然过期,此时大量请求同时查询该 Key,瞬间穿透到数据库,导致数据库短时间压力暴增(类似 “单点突破”)。
- 一句话例子:某网红口红的缓存 Key(“goods:10086”)过期,同一秒有 1 万用户查询该口红,缓存查不到,1 万次请求全打给数据库,数据库瞬间卡顿。
2、解决办法
热点 Key “永不过期”:
对核心热点 Key(如首页数据、TOP10 商品)不设置过期时间,通过业务代码主动更新缓存(如商品库存变了就同步更新缓存)。
互斥锁(分布式锁):
- 当缓存 Key 过期时,只允许一个请求去数据库查数据并更新缓存,其他请求等待该请求更新完缓存后,再从缓存获取数据(用 Redis 的 SETNX 命令实现锁)。
二、雪崩(大量key)
1、描述
- 问题定义:短时间内大量 Redis 缓存 Key 同时过期,或 Redis 服务宕机,导致所有请求瞬间穿透到数据库,引发数据库压力骤增甚至宕机。
- 一句话例子:电商平台 “双 11” 零点有 10 万件商品的缓存同时过期,用户查询这些商品的请求全打到数据库,数据库直接崩了。
2、解决方案
- 缓存过期时间 “加随机值”:给每个 Key 的过期时间加 5-10 分钟随机数,避免集中过期(如原 1 小时过期,改为 3600±300 秒)。
- 服务熔断 / 限流:用 Sentinel、Hystrix 等工具,当数据库压力超阈值时,暂时拒绝部分请求,避免数据库过载。
- Redis 集群高可用:部署主从 + 哨兵或 Redis Cluster,防止单节点宕机导致整个缓存不可用。
三、穿透(无数据)
1、描述
- 问题定义:请求查询的是 “不存在的数据”(如查 ID=-1 的用户),这类数据既不在 Redis 缓存,也不在数据库,导致请求每次都穿透到数据库,长期积累会压垮数据库。
- 一句话例子:黑客用脚本批量查询 “ID=9999999”“ID=-123” 等不存在的用户,缓存查不到,所有请求全打给数据库,数据库 CPU 飙升到 100%。
2、解决办法
- 缓存 “空值”:对查询结果为 null 的数据,也在 Redis 缓存(如 Key=“user:9999999”,Value=null),并设置短过期时间(如 5 分钟),避免重复穿透。
- 布隆过滤器(Bloom Filter):提前将数据库中所有 “存在的 Key”(如合法用户 ID、商品 ID)存入布隆过滤器,请求先过过滤器 —— 不存在的 Key 直接拦截,不进缓存和数据库。
- 还可以在接收请求是判断是否合法,将不合法的请求直接返回屏蔽。合法的数据再放行