你刚给服务器换上新SSD,搭好Redis集群,结果某天凌晨三点,用户全进不去网站,监控显示缓存层直接崩了——这不是硬盘问题,是缓存雪崩在搞鬼。
啥叫缓存雪崩?
简单说,就是大量缓存key在同一时间过期,或者Redis挂了,所有请求瞬间打到数据库,数据库扛不住就卡死。就像早高峰地铁闸机全坏了,人群全堵在入口,谁都进不去。
别光靠加机器,这几招更管用
装机不是堆硬件,架构设计才是关键。我们平时调Redis、配Nginx、写脚本时,顺手加点小动作,就能避开大坑。
1. 过期时间加随机数
别让一堆热点商品缓存都设成 EXPIRE 3600。写入时随手加个±300秒的浮动:
SET product:1001 "{'name':'机械键盘','price':399}" EX 3600 PX 300000或者代码里生成: expireTime = 3600 + random.randint(0, 300)。几十万条缓存错开5分钟,压力就分散开了。
2. 缓存永不过期 + 后台异步更新
对读多写少的数据(比如省份列表、常见品牌),干脆不设过期时间,靠后台定时任务刷新:
# 每10分钟拉一次最新数据,更新缓存
0 */10 * * * /usr/bin/curl -s http://localhost:8080/api/refresh-brands > /dev/null既没过期洪峰,又保证数据基本新鲜。
3. 加个本地缓存兜底
别把鸡蛋全放Redis篮子里。Java项目加个Caffeine,Python用diskcache,Node.js配lru-cache。哪怕Redis断了,本地还能扛住几百QPS:
const cache = new LRUCache({ max: 500 });
app.get('/api/product/:id', async (req, res) => {
const local = cache.get(req.params.id);
if (local) return res.json(local);
// 再查Redis或DB
});4. 限流+熔断,关键时刻能刹车
Nginx配个简单限流,防数据库被冲垮:
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
location /api/ {
limit_req zone=api burst=200 nodelay;
proxy_pass http://backend;
}再配合Sentinel或Resilience4j做熔断,连续5次DB超时,就自动切到默认空数据或降级页面,等缓存恢复再切回来。
顺手检查三件事
• 查Redis慢日志:redis-cli --latency -p 6380,确认没大KEY拖慢整体响应;
• 看监控里key过期曲线,是不是整点扎堆(比如每小时0分集中过期);
• 检查应用启动时有没有批量预热缓存,别等用户来敲门才现加载。
缓存不是越快越好,而是越稳越香。SSD再快,也架不住缓存一崩,整个服务跟着瘫。装机看配置,运维看细节,这两块都盯住了,半夜告警才能少响几次。