Redis 缓存穿透解决
时间:2026-10-8 07:23 作者:emer 分类: 无
Redis 缓存穿透解决
缓存穿透是指查询不存在的数据,请求都打到数据库,可能被攻击。
1. 什么是缓存穿透
- 缓存里没有这个数据
- 数据库里也没有
- 每次请求都查数据库
- 有人恶意攻击数据库就挂了
2. 和其他问题的区别
- 穿透: 查不存在的数据
- 击穿: 热点key过期
- 雪崩: 大量key同时过期
3. 解决方案
方案一:缓存空值
function getUser($id) {
global $redis, $db;
$key = "user:".$id;
$user = $redis->get($key);
if ($user !== false) {
return json_decode($user, true);
}
// 查数据库
$user = $db->query("SELECT * FROM users WHERE id=$id");
if ($user) {
// 存正常数据
$redis->setex($key, 3600, json_encode($user));
} else {
// 存空值,短时间过期
$redis->setex($key, 60, "null");
}
return $user;
}
方案二:布隆过滤器
- 所有存在的数据存在布隆过滤器里
- 查询前先过布隆过滤器
- 不存在直接返回,不查数据库
方案三:接口校验
- 前端做参数校验
- 比如id必须大于0
- 不合法的直接拒绝
4. 代码示例
// 简单防穿透
if ($id <= 0) {
return null;
}
// 先查缓存
$user = $redis->get("user:".$id);
if ($user === "null") {
return null;
}
if ($user) {
return json_decode($user, true);
}
// 查数据库
$user = $db->query("SELECT * FROM users WHERE id=$id");
// 存缓存
if ($user) {
$redis->setex("user:".$id, 3600, json_encode($user));
} else {
$redis->setex("user:".$id, 60, "null");
}
return $user;
5. 最佳实践
- 空值缓存,短时间过期
- 重要接口加布隆过滤器
- 前端做参数校验
- 数据库做限流保护
总结
缓存穿透解决要点:
- 查不到也存空值
- 空值过期时间短
- 用布隆过滤器
- 做好接口校验
高并发系统,缓存穿透一定要防。