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 次