340 words
2 minutes
Redis 缓存雪崩、击穿、穿透详解

缓存是提升系统性能的关键,但使用不当会带来严重问题

缓存雪崩#

问题描述#

大量缓存 key 在同一时间过期,导致大量请求直接打到数据库,造成数据库压力激增。

解决方案#

// 方案1:设置随机过期时间
const expireTime = baseTime + Math.random() * 3600;
// 方案2:使用分布式锁
const lock = await redis.lock('product:1', 3000);
if (lock) {
const data = await db.queryProduct(1);
await redis.setex('product:1', 3600, JSON.stringify(data));
await redis.unlock(lock);
}
TIP

建议缓存过期时间设置分散,避免集中过期。

缓存击穿#

问题描述#

某个热点 key 过期瞬间,大量并发请求直接打到数据库。

解决方案#

使用互斥锁或永不过期策略:

const cache = await redis.get('hot:product:1');
if (!cache) {
const lock = await redis.setnx('lock:product:1', '1', 'EX', 10);
if (lock) {
const data = await db.queryProduct(1);
await redis.set('hot:product:1', JSON.stringify(data));
}
}

缓存穿透#

问题描述#

查询一个不存在的 key,每次都打到数据库。

解决方案#

  1. 布隆过滤器
  2. 空值缓存
// 布隆过滤器判断key是否存在
if (bloomFilter.test(key)) {
const result = await db.query(key);
if (!result) {
// 缓存空值
await redis.setex(key, 300, 'NULL');
}
}

总结#

问题原因方案
雪崩大量key同时过期随机过期时间
击穿热点key过期永不过期/互斥锁
穿透查询不存在数据布隆过滤器/空值缓存