Redis 缓存三大坑:穿透、击穿、雪崩

举报
Brian-Tony 发表于 2026/11/07 00:19:26 2026/11/07
【摘要】 Redis 缓存三大坑:穿透、击穿、雪崩缓存是提升系统性能最直接的手段,但缓存一旦出问题,轻则响应变慢,重则直接打垮数据库。面试里经常把"穿透、击穿、雪崩"三个概念放在一起问,很多人容易搞混。今天就来逐个拆解,顺便聊聊对应的解决方案。 缓存穿透现象:查询一个根本不存在的数据,缓存不命中,请求直接打到数据库,数据库也查不到,于是每次请求都穿透到 DB。如果攻击者故意用大量不存在的 key 发...

Redis 缓存三大坑:穿透、击穿、雪崩

缓存是提升系统性能最直接的手段,但缓存一旦出问题,轻则响应变慢,重则直接打垮数据库。面试里经常把"穿透、击穿、雪崩"三个概念放在一起问,很多人容易搞混。今天就来逐个拆解,顺便聊聊对应的解决方案。

缓存穿透

现象:查询一个根本不存在的数据,缓存不命中,请求直接打到数据库,数据库也查不到,于是每次请求都穿透到 DB。

如果攻击者故意用大量不存在的 key 发起请求,数据库可能被瞬间打满。

解决方案:

  1. 缓存空值:数据库查不到也往缓存里写一个空值(比如 null 或特殊标记),设置一个较短的过期时间。下次同样请求直接返回空,不再查库。缺点是会占用一些缓存空间。
  2. 布隆过滤器(Bloom Filter):在缓存之前加一层布隆过滤器,把所有存在的 key 预先加载进去。请求来时先过布隆过滤器,如果判断不存在就直接返回,不会查缓存和数据库。布隆过滤器有一定的误判率(可能把不存在的判为存在),但不会漏判,空间效率极高。
  3. 参数校验:在接口层做合法性校验,比如 id 必须为正整数、字符串长度有限制等,把明显不合法的请求拦截在门外。

缓存击穿

现象:某个热点 key 突然过期,此时恰好有大量并发请求同时访问这个 key,所有请求都穿透到数据库,造成瞬时压力。

和穿透的区别:穿透查的是"不存在的数据",击穿查的是"存在但刚好过期的热点数据"。

解决方案:

  1. 热点数据永不过期:对极热点的 key 不设置过期时间,或者设置一个很长的时间。如果需要更新,通过后台任务异步刷新缓存。
  2. 互斥锁(Mutex Lock):当缓存失效时,不是所有线程都去查库,而是用分布式锁(如 Redis 的 SETNX)让一个线程去查库重建缓存,其他线程等待或返回旧值。
public String getData(String key) {
    String value = redis.get(key);
    if (value == null) {
        // 尝试获取锁
        if (redis.setnx(key + ":lock", "1", 10)) {
            try {
                // 双重检查
                value = redis.get(key);
                if (value == null) {
                    value = db.query(key);
                    redis.set(key, value, 300);
                }
            } finally {
                redis.del(key + ":lock");
            }
        } else {
            // 没拿到锁,短暂等待后重试
            Thread.sleep(50);
            return getData(key);
        }
    }
    return value;
}
  1. 逻辑过期:缓存中不存真实的过期时间,而是把过期时间作为 value 的一部分。读取时发现逻辑上已过期,异步启动一个线程去重建缓存,当前请求先返回旧值。

缓存雪崩

现象:大量 key 在同一时间集中过期,或者 Redis 实例宕机,导致大量请求瞬间涌向数据库。

和击穿的区别:击穿是"单个热点 key"过期,雪崩是"大批 key"同时失效。

解决方案:

  1. 过期时间加随机值:给缓存的过期时间加上一个随机偏移量(比如基础时间 + 1~5 分钟随机),避免大量 key 同时过期。
  2. Redis 高可用:用 Redis Sentinel 或 Redis Cluster 做主从复制和故障转移,避免单点故障。
  3. 限流降级:在缓存层和数据库层之间加限流(如 Sentinel、Hystrix),超出阈值的请求直接返回降级结果,保护数据库不被打垮。
  4. 多级缓存:本地缓存(如 Caffeine)+ Redis 缓存 + 数据库,即使 Redis 挂了,本地缓存还能扛一部分流量。

三者对比

类型 原因 关键特征 核心解法
穿透 查询不存在的数据 缓存和 DB 都没有 缓存空值、布隆过滤器
击穿 热点 key 过期 单个 key 高并发 互斥锁、热点永不过期
雪崩 大量 key 同时过期 / Redis 宕机 大面积缓存失效 过期时间随机、高可用、限流

一句话总结

  • 穿透防的是"不存在的 key",用布隆过滤器或缓存空值。
  • 击穿防的是"热点 key 过期",用互斥锁或逻辑过期。
  • 雪崩防的是"大面积失效",用随机过期时间 + 高可用 + 限流。
  • 实际项目中通常是组合使用,没有银弹。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。