Laravel 缓存实战:用 Redis 防穿透、防击穿、防雪崩的三道防线
test12026-09-122 次阅读
缓存三大经典问题
用 Redis 做缓存时,穿透、击穿、雪崩是三道绕不开的坎。它们名字像,根因和解决手段却不同,下面分别给出可落地的代码。
防穿透:缓存空值
穿透指查询一个根本不存在的数据,请求每次都越过缓存打到数据库。解决:即使查不到也缓存一个短生命的空标记。
use Illuminate\Support\Facades\Cache;
function getUser(int $id): array
{
return Cache::remember("user:{$id}", 300, function () use ($id) {
$u = DB::table('users')->find($id);
// 查不到也缓存空标记,避免重复穿透到 DB
return $u ? (array) $u : ['__null__' => true];
});
}
防击穿:热点 key 加锁重建
击穿指一个极热 key 刚好过期,瞬间大量请求同时重建缓存。解决:用分布式锁让只有一个请求去查库,其余等待缓存就绪。
function getHotConfig(): array
{
$key = 'config:hot';
if ($cached = Cache::get($key)) return $cached;
return Cache::lock("lock:{$key}", 3)->block(3, function () use ($key) {
// 双重检查,避免锁等待期间别人已写入
if ($cached = Cache::get($key)) return $cached;
$data = DB::table('config')->pluck('value', 'key')->toArray();
Cache::put($key, $data, 600);
return $data;
});
}
防雪崩:过期时间加抖动
雪崩指大量 key 在同一时刻集体过期,数据库瞬时压力爆棚。解决:给 TTL 加随机抖动,错开过期时间。
function cacheWithJitter(string $key, $data, int $base): void
{
$ttl = $base + random_int(0, 300);
Cache::put($key, $data, $ttl);
}
小结
- 穿透:缓存空值,必要时用布隆过滤器兜底不存在的键。
- 击穿:分布式锁保证单飞重建,加双重检查。
- 雪崩:TTL 随机抖动,热点 key 设为不过期或错峰刷新。
T
test1
文章作者
缓存三大经典问题 用 Redis 做缓存时,穿透、击穿、雪崩是三道绕不开的坎。它们名字像,根因和解决手段却不同,下面分...
- 分类
- 技术
- 发布时间
- 2026-09-12
- 字数
- 约 1211 字
- 阅读
- 2 次
