spring的技术笔记
后端1 分钟阅读

Redis 缓存模式:Cache-Aside 与三大经典故障

用 Cache-Aside 落地读写路径,并准备击穿、穿透、雪崩的防护清单。

缓存不是「把结果塞进 Redis」就结束。真正要设计的是:谁负责读写、失败怎么降级、热点怎么护住数据库。

Cache-Aside(旁路缓存)

读路径:

async function getPost(slug: string) {
  const cached = await redis.get(`post:${slug}`);
  if (cached) return JSON.parse(cached);
 
  const post = await db.posts.findBySlug(slug);
  if (post) {
    await redis.set(`post:${slug}`, JSON.stringify(post), "EX", 300);
  }
  return post;
}

写路径:先更新 DB,再删缓存(或短延迟双删)。用「更新缓存」代替「删除」时要小心并发写脏。

三种故障

  1. 击穿:热点 key 过期,并发全打 DB → 互斥重建或逻辑过期。
  2. 穿透:查询不存在的数据反复打穿 → 缓存空值(短 TTL)或布隆过滤器。
  3. 雪崩:大量 key 同时过期 → TTL 加抖动;多级缓存;依赖隔离。
const ttl = 300 + Math.floor(Math.random() * 60); // 抖动
await redis.set(key, value, "EX", ttl);

实践建议

  • Key 命名带业务域:post:{slug}、user:{id}:profile。
  • 设定可观测性:命中率、重建耗时、DB QPS。
  • 不是所有读都该缓存;先缓存「贵且稳」的查询。

小结

缓存模式选对之后,把故障预案写进运行手册。等促销或热点文章来了再补,通常已经晚了。