跳转至

高并发热点缓存如何重建

一、什么是热点 Key

某些 Key 被超高并发访问,比如首页、商品详情、明星信息。Redis 扛不住,DB 也扛不住。

二、缓存过期瞬间的问题

热点 Key 过期: 1. 大量请求同时打到 DB。 2. DB 被打挂。 3. 缓存重建期间,请求排队。

三、解决方案

1. 永不过期

  • 逻辑过期:Redis 不设 TTL,value 里存过期时间。
  • 读时发现过期,异步更新。
  • 适合对一致性要求不高的场景。
if (data.expireTime < now) {
    asyncReload();   // 异步重建
    return oldData;  // 返回旧数据
}

2. 互斥锁重建

只让一个线程去重建,其他等旧值:

String lock = "lock:" + key;
if (redis.setnx(lock, "1", 5, SECONDS)) {
    // 拿到锁,重建
    data = loadFromDB();
    redis.set(key, data, ttl);
    redis.del(lock);
} else {
    sleep(100);
    return redis.get(key);  // 重试
}

3. 提前续期(后台线程)

热点 Key 由后台线程提前续期,不让它过期。

4. 多级缓存

  • L1:本地缓存(Caffeine)。
  • L2:Redis。
  • L3:DB。

热点数据放本地缓存,减少 Redis 压力。

5. 热点 Key 分散

把一个热点 Key 拆成多个(如 product:123:0product:123:1),分摊到多个 Redis 节点。

四、推荐方案

  • 一致性要求高:互斥锁重建。
  • 一致性要求低:逻辑过期 + 异步重建。
  • 超热点:本地缓存 + 预热。

五、预热

系统启动时把热点数据提前加载到 Redis,避免冷启动被打挂。

注意

  • 不要用 synchronized 在应用层锁,分布式下不生效。
  • 分布式锁要设过期时间,防止死锁。