Redis 缓存穿透解决
时间:2026-10-4 10:43 作者:emer 分类: 无
Redis 缓存穿透解决方案
缓存穿透是指查询一个数据库里根本不存在的数据,因为缓存里也没有,所以每次请求都打到数据库。如果有人恶意攻击,数据库可能被打挂。
什么是缓存穿透
正常流程:先查缓存,缓存有就直接返回,没有再查数据库,然后写入缓存。
如果查询的数据数据库里也没有,那缓存永远都不会命中,每次请求都会查数据库,这就是缓存穿透。
解决方案一:缓存空值
最简单的办法,数据库查不到也往缓存里写一个空值,设个短过期时间。
$data = $redis->get($key);
if ($data === null) {
$data = $db->query($sql);
if ($data === null) {
// 缓存空值,60秒过期
$redis->setex($key, 60, '');
} else {
$redis->setex($key, 3600, $data);
}
}
优点:简单直接
缺点:会占用更多缓存空间,大量空值缓存会浪费内存
解决方案二:布隆过滤器
在缓存前面加一层布隆过滤器,先判断数据是否存在,不存在直接返回。
布隆过滤器的原理是用一个大的位数组和多个哈希函数,把存在的数据标记为1。查询时如果所有哈希位置都是1,说明可能存在;只要有一个位置是0,说明一定不存在。
优点:内存占用小,效率高
缺点:有一定误判率(说存在可能不存在,说不存在一定不存在)
两种方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 缓存空值 | 简单 | 浪费内存 | 数据量小,穿透不严重 |
| 布隆过滤器 | 内存效率高 | 有误差 | 数据量大,穿透严重 |
总结
缓存穿透是常见的缓存问题,小项目用缓存空值就够了,大项目数据量大就上布隆过滤器。两种方案都能解决问题,根据实际场景选就行。