Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

    • Redis 缓存击穿问题及解决方案
      • 缓存雪崩问题及解决方案
      • 缓存穿透及解决方案
      • 设计 Redis 的 key 和 value ,有哪些原则?
    • 多线程类

    • JVM 类

    • MySQL 类

    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • 缓存问题类
    刘博
    2025-12-28
    目录

    Redis 缓存击穿问题及解决方案

    # 什么是缓存击穿

    缓存击穿是 “一个热点 Key(如热门商品详情、热门文章)过期时,大量并发请求同时穿透缓存,直接查询数据库,导致数据库瞬间压力骤增” 的问题。与缓存穿透(查询不存在的 Key)不同,击穿的 Key 是真实存在的,只是恰好过期。

    # 解决方案

    • 1. 热点 Key 永不过期:

      • 对热点 Key 不设置过期时间(expire),避免 Key 过期导致的击穿;
      • 同时在后台启动定时任务,定期更新热点 Key 的 value(如每 10 分钟更新一次热门商品库存),确保数据一致性。
      • 优点:实现简单,无并发问题;缺点:占用 Redis 内存(若热点 Key 过多),需确保定时任务可靠。
    • 2. 互斥锁(分布式锁):

      • 当请求查询缓存时,若 Key 不存在,先通过 Redis 的setNx(set if not exists)获取分布式锁,只有获取到锁的请求才能查询数据库,查询后更新缓存,其他请求则等待(如自旋重试或休眠),直到缓存更新完成。

      • 示例(伪代码):

        java 运行

      public Object getHotData(String key) {
          // 1. 查询缓存
          Object data = redis.get(key);
          if (data != null) return data;
          // 2. 获取分布式锁
          boolean lock = redis.setNx("lock:" + key, "1", 5); // 锁过期时间5秒,避免死锁
          if (lock) {
              try {
                  // 3. 再次查缓存(防止其他请求已更新)
                  data = redis.get(key);
                  if (data != null) return data;
                  // 4. 查数据库
                  data = db.query(key);
                  // 5. 更新缓存(设置过期时间)
                  redis.set(key, data, 300); // 5分钟过期
                  return data;
              } finally {
                  // 6. 释放锁
                  redis.delete("lock:" + key);
              }
          } else {
              // 7. 未获取到锁,重试(休眠100ms后再次查询)
              Thread.sleep(100);
              return getHotData(key);
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
    • 优点:确保只有一个请求查数据库,保护数据库;缺点:存在锁竞争,请求可能等待,影响接口响应时间。

    • 3. 预热缓存:

      • 在系统上线前或流量高峰来临前(如电商大促),通过脚本或后台任务将热点 Key 提前加载到 Redis,并设置合理的过期时间;
      • 例如:大促前 1 小时,将 Top1000 热门商品的详情数据加载到 Redis,过期时间设为大促结束后。
      • 优点:从源头避免 Key 过期导致的击穿;缺点:需提前识别热点 Key,对未知热点 Key 无效。

    上次更新: 12/30/2025
    声明式事务的实现原理(AOP)
    缓存雪崩问题及解决方案

    ← 声明式事务的实现原理(AOP) 缓存雪崩问题及解决方案→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式