《Redis 缓存穿透、击穿与雪崩:一次讲清三者的区别和解法》
【摘要】 前言前几天在论坛回答了一个"Redis 缓存穿透如何解决"的问题,写完发现这三个概念特别容易混:穿透、击穿、雪崩,名字像,成因和解法却完全不一样。这篇把三者一次讲清,顺手记下各自的应对办法。 一、缓存穿透:查了个不存在的东西穿透是指请求的数据在缓存和数据库里都不存在,每次请求都会穿过缓存打到数据库。恶意构造大量不存在的 key 就能把数据库拖垮。解法有三个,经常组合用:缓存空值:查不到时也...
前言
前几天在论坛回答了一个"Redis 缓存穿透如何解决"的问题,写完发现这三个概念特别容易混:穿透、击穿、雪崩,名字像,成因和解法却完全不一样。这篇把三者一次讲清,顺手记下各自的应对办法。
一、缓存穿透:查了个不存在的东西
穿透是指请求的数据在缓存和数据库里都不存在,每次请求都会穿过缓存打到数据库。恶意构造大量不存在的 key 就能把数据库拖垮。
解法有三个,经常组合用:
- 缓存空值:查不到时也在缓存里存一个空结果,并设置较短的过期时间,避免空值被长期占用,也避免后续正常写入后还读到空值。
- 布隆过滤器:在缓存前面挡一道,先判断 key 是否可能存在,不存在直接返回,不进数据库。布隆过滤器有极小误判率,但不会漏判存在的数据,适合做前置拦截。
- 参数校验:在网关或接口层先校验请求参数的合法性,不合法的请求根本不进缓存查询链路。
二、缓存击穿:热点 key 刚好过期了
击穿是指某个热点 key 在过期的一瞬间,大量并发请求同时发现缓存没了,一起涌向数据库。问题不在数据不存在,而在过期那一刻的并发。
常用解法:
- 热点 key 永不过期:对极少数热点 key 干脆不设过期时间,改由后台任务定时刷新。
- 互斥锁:只放一个请求去数据库加载并回填缓存,其他请求短暂等待或读旧值,避免并发打爆数据库。
- 逻辑过期:缓存里多存一个逻辑过期时间戳,过期后先返回旧值,再由一个线程异步刷新,请求不用等。
三、缓存雪崩:大面积 key 同时过期
雪崩是指大量 key 在同一时间点过期,或者缓存服务本身宕机,请求瞬间全部落到数据库。
解法:
- 过期时间加随机值:给每个 key 的过期时间加上一段随机偏移,避免同一时刻集体过期。
- 多级缓存:本地缓存 + Redis 两级,Redis 挂了还有本地缓存顶一阵。
- 限流与熔断:网关层限流,数据库前面加熔断保护,避免雪崩演变成全站不可用。
- 缓存预热:服务启动或大促前先把热点数据主动加载进缓存,别等请求来了现查。
四、三者怎么区分
| 现象 | 本质 | 关键词 |
|---|---|---|
| 穿透 | 数据根本不存在 | 查无此物 |
| 击穿 | 单个热点 key 过期瞬间并发 | 一个 key |
| 雪崩 | 大面积 key 同时失效 | 一大片 |
记住这个表,面试或排查时先定位是哪一种,再选对应的解法,别一上来就加布隆过滤器——击穿和雪崩用布隆过滤器是没用的。
五、配套的监控习惯
不管用哪种解法,都建议把三类指标看住:缓存命中率、慢查询和数据库连接数。命中率突然掉、数据库连接数突然涨,往往就是三者之一正在发生的信号,早发现比事后救火便宜得多。
结语
穿透防"无中生有"的请求,击穿防"热点过期"那一刻,雪崩防"集体过期"那一片。先分清现象,再选解法,这三个问题其实都不难。
备注:本文整理自作者在华为云开发者论坛的相关回答与公开资料;未涉及任何生产环境实测数据。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)