Redis 缓存击穿的三种解法
互斥锁、逻辑过期与永不过期的取舍。
击穿、雪崩、穿透的区别
- 击穿:某个热点 key 过期瞬间,大量请求同时打到数据库
- 雪崩:大批 key 同时过期
- 穿透:查询根本不存在的数据,缓存永远不命中
本文只谈击穿。
解法一:互斥锁
只放一个请求去重建缓存,其余等待。实现简单,但等待的请求会被拖慢。
if ($redis->set($lockKey, 1, ['nx', 'ex' => 10])) {
$data = $this->rebuild();
$redis->setex($key, 3600, serialize($data));
$redis->del($lockKey);
}
解法二:逻辑过期
value 里存一个业务过期时间,key 本身永不过期。读到「逻辑上过期」时异步重建,当前请求先返回旧值。
一致性换可用性,适合能容忍短暂陈旧的场景。
解法三:永不过期 + 主动更新
数据变更时同步刷缓存。最干净,但要求所有写入点都记得刷——绕过模型层直接写库就会漏。
选型标准很简单:能容忍陈旧就用逻辑过期,不能容忍就用互斥锁。
评论0





暂无评论,期待您的发言...