欢迎光临
我们一直在努力

redis缓存雪崩,击穿,穿透,到底是什么?

Redis 缓存雪崩、击穿、穿透 是缓存使用中最经典的三大“灾难级”问题,几乎所有中大型系统都会遇到,也几乎是面试中 Redis 相关问题出现频率 Top 3 的概念。

下面用最通俗、最容易记住的方式给你讲清楚三者的定义、成因、危害、区别、解决方案。

一张表先看清三者的本质区别

问题名称什么时候发生核心原因影响范围表现形式典型场景举例
缓存穿透 查询一个根本不存在的数据 请求直接打到数据库 单个 key 反复打穿 数据库压力瞬间暴增 黑客猜用户 ID、恶意爬虫刷不存在的商品 ID
缓存击穿 某个热点 key 突然过期 大量并发同时请求同一个已过期 key 单个热点 key 瞬间把数据库打崩 秒杀商品、热门文章、直播间人数
缓存雪崩 大量 key 在同一时间点集体失效 大量缓存同时过期 + 冷启动 几乎所有 key 数据库像雪崩一样瞬间被打垮 双11零点、促销活动统一设置了相同过期时间

详细解释 + 生活化比喻

1. 缓存穿透(Cache Penetration)

比喻: 你去一个从没开过门的店问“有没有黄金项链”,老板每次都要去仓库翻一遍告诉你“没有”,你一天问 10 万次,老板累死了。

成因:

  • 查询一个数据库里压根不存在的数据
  • 缓存里自然也没有 → 每次都穿透到数据库

最危险的几种情况:

  • 恶意攻击(枚举不存在的 ID)
  • 前端传了非法参数(负数 ID、空字符串、超大值)
  • 数据库里数据被删除了,但缓存没清理

解决方案(按优先级排序):

  • 缓存空结果(最常用)

    if (redis.get(key) == null) {
    Object obj = db.query(id);
    if (obj == null) {
    redis.setex(key, 60, "EMPTY"); // 缓存空值,短过期时间
    } else {
    redis.setex(key, 3600, obj);
    }
    }

  • 布隆过滤器(适合黑客攻击场景)

    • 在缓存前加一层布隆过滤器,提前判断 key 肯定不存在就直接返回
  • 接口参数校验 + 限流 + IP 黑名单

  • 2. 缓存击穿(Cache Breakdown / Hot Key 失效)

    比喻: 商场里最火的那件限量款羽绒服突然卖完了(缓存过期),门口瞬间挤了几千人同时问“还有货吗”,全都冲到仓库去问老板。

    成因:

    • 一个极热的 key(QPS 几千上万)
    • 恰好在这个时间点过期
    • 大量请求同时穿透到数据库

    解决方案(目前主流做法):

  • 永不过期 + 逻辑过期(最推荐)

    // 缓存里存两个字段:data + expireTime
    if (now > expireTime) {
    // 异步线程去刷新
    asyncRefresh(key);
    return oldData; // 先返回旧数据
    }

  • 加分布式锁(setnx / Redisson lock)

    • 只有一个请求去查数据库,其他请求等待或返回旧数据

    if (lock.tryLock(10, TimeUnit.SECONDS)) {
    try {
    // 双重检查
    if (redis.get(key) == null) {
    redis.setex(key, 3600, db.query());
    }
    } finally {
    lock.unlock();
    }
    }

  • 热点 key 预加载 / 随机偏移过期时间

  • 3. 缓存雪崩(Cache Avalanche)

    比喻: 商场里 80% 的商品同时到保质期,全都下架了,几万人同时冲向仓库,仓库直接被挤爆。

    成因:

    • 大量 key 在同一时间点过期
    • 或者缓存服务器宕机 / 重启 / 冷启动

    解决方案(多管齐下):

  • 过期时间加随机值

    redis.setex(key, 3600 + random(300, 600), value); // 1小时 ± 几分钟

  • 多级缓存(本地缓存 + Redis)

    • Caffeine / Guava Cache 做一级,本地命中就不打 Redis
  • 热点数据永不过期 + 定时任务后台刷新

  • Redis 集群 + 主从 + 哨兵,避免单点宕机

  • 熔断 / 降级 / 限流(Hystrix、Resilience4j、Sentinel)

  • 缓存预热(启动时把热点数据提前加载)

  • 三者对比总结口诀(面试背这个就够)

    • 穿透:查根本不存在的东西 → 缓存空对象 / 布隆过滤器
    • 击穿:一个超级热点突然没了 → 分布式锁 / 逻辑过期 / 永不过期
    • 雪崩:一大堆 key同时没了 → 随机过期 + 多级缓存 + 预热

    一句话记住: 穿透是“查鬼”,击穿是“抢购疯抢一件”,雪崩是“商场同时清仓”。

    你现在项目里有没有遇到过这三个问题中的哪一个? 或者想看某个具体解决方案的代码示例(比如分布式锁防击穿、布隆过滤器防穿透)?可以继续问~

    赞(0)
    未经允许不得转载:171主机测评 » redis缓存雪崩,击穿,穿透,到底是什么?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址