缓存雪崩是大量缓存集体失效导致数据库瞬间过载;PHP中表现为Redis::get大量返回null后mysqli_query/PDO::query出现连接超时、CPU飙升、慢日志暴增,常见于定时刷新或同TTL设置场景。
缓存雪崩是什么,PHP里怎么一眼识别
缓存雪崩不是慢,是集体失效后数据库被瞬间打穿。在 PHP 中典型表现是:Redis::get() 大量返回 null,紧接着 mysqli_query() 或 PDO::query() 出现连接超时、CPU 突升、慢日志暴增。尤其发生在定时任务刷新缓存后、或大量 key 设置了相同过期时间(比如都设 3600 秒)的场景。
给缓存加随机过期时间(最简单有效的防线)
别让所有 key 在同一秒过期。PHP 中设置缓存时,在基础 TTL 上叠加一个随机偏移量:
```php $baseTtl = 3600; // 1小时 $randomOffset = rand(0, 600); // ±10分钟 $ttl = $baseTtl + $randomOffset;$redis->setex($key, $ttl, $value);
<pre class='brush:language-
;toolbar:false;’>
- 偏移量建议控制在基础 TTL 的 10%–20%,太小没用,太大影响一致性
- 不要用
time() + $ttl算过期时间再存——setex/set的EX参数才是原子性保障 - 如果用
apcu_store(),也得手动加随机:apcu_store($key, $value, $ttl + rand(0, 300))
用互斥锁(mutex)挡住并发回源请求
当缓存失效时,多个 PHP-FPM 进程同时发现没数据,都会去查 DB——这就是“击穿+雪崩”的温床。必须只放行一个进程重建缓存: