«

Redis缓存穿透击穿雪崩区别与防护方案

时间:2026-10-19 07:23     作者:emer     分类: 无


前言

Redis 把热点数据放进内存提速,但缓存一旦失效或被恶意穿透,数据库会被瞬间打垮。很多人把穿透、击穿、雪崩混为一谈,三者成因不同,防护手段也不一样,本篇一次讲清区别和方案。

一、缓存穿透:查不存在的数据

攻击者或程序反复查询一个数据库里根本不存在的 key,缓存永远不命中,每次都打到 MySQL。

// 伪代码:缓存空值
$user = $db->find($id);
if ($user === null) {
    $redis->setex("u:$id", 60, 'NULL');
    return null;
}
$redis->setex("u:$id", 3600, json_encode($user));

二、缓存击穿:热点key过期瞬间

一个被高频访问的热点 key 突然过期,大量并发同时打到数据库重建缓存。和穿透区别:数据真实存在,只是刚好过期。

// SETNX 单线程重建
$lock = $redis->setnx("lock:u:$id", 1);
if ($lock) {
    $redis->expire("lock:u:$id", 10);
    $data = $db->find($id);
    $redis->setex("u:$id", 3600, json_encode($data));
}

三、缓存雪崩:大量key同时过期

大批缓存同一时间失效,数据库承压暴增。和击穿区别:击穿是单个热点,雪崩是大面积。

$ttl = 3600 + mt_rand(0, 600); // 3600~4200 秒随机
$redis->setex("list:$page", $ttl, json_encode($rows));

四、三者对比速记

总结

先分清"查不存在""单点过期""批量过期"三种场景,再对应布隆过滤器、互斥锁、随机TTL,就能把数据库挡在缓存后面。

遇到问题加QQ23979811 协助处理