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,每次都打到数据库。
解决方案
- 布隆过滤器
- 空值缓存
// 布隆过滤器判断key是否存在if (bloomFilter.test(key)) { const result = await db.query(key); if (!result) { // 缓存空值 await redis.setex(key, 300, 'NULL'); }}总结
| 问题 | 原因 | 方案 |
|---|---|---|
| 雪崩 | 大量key同时过期 | 随机过期时间 |
| 击穿 | 热点key过期 | 永不过期/互斥锁 |
| 穿透 | 查询不存在数据 | 布隆过滤器/空值缓存 |