Redis如何构建防缓存穿透系统_从用户输入验证到布隆过滤器

雨强小哥_8707

雨强小哥_8707

2026-05-03

934人浏览

原创

校验必须在缓存层之前:对ID用类型转换过滤,字符串key限定长度与字符集;空值缓存需加随机TTL防击穿,布隆过滤器须与DB更新强同步;Key应分离存在性与数据内容。

redis如何构建防缓存穿透系统_从用户输入验证到布隆过滤器

用户输入校验必须在缓存层之前做

缓存穿透本质是非法或不存在的 key 持续打到后端,所以第一道防线不是 Redis,而是业务入口。如果用户传 id=abc 这种明显非数字 ID,或者空字符串、超长字符串、SQL 片段,根本别让它进缓存查询流程。

  • 对 ID 类参数,用正则或类型转换快速过滤:parseInt(id) 后判断是否为有效整数,isNaN() 为 true 就直接拒绝
  • 对字符串类 key(如用户名),限定长度(如 2–32 字符)、字符集(/^[a-zA-Z0-9_\-]+$/),不满足就返回 400
  • 不要依赖 Redis 返回 null 再做判断——那已经穿透了一次,且可能被恶意放大
  • Web 框架层(如 Express 中间件、Spring MVC @Valid)做校验比在 service 层更早、更省资源

空值缓存不能只设固定过期时间

把 null 或空对象写进 Redis 是常见手段,但只设 EX 60 很危险:热点空 key 被高频请求时,缓存一过期就集体击穿;冷门空 key 又长期占内存。

  • 对明确不存在的 key(如已删除商品 ID),用短 TTL + 随机偏移:SET goods:999999 "" EX 60 PX 5000,避免雪崩
  • 对“暂时查无结果”(比如异步任务未完成),建议用带业务语义的占位值,如 "pending",并配合单独的轻量轮询机制
  • 注意:Redis 6.2+ 支持 SET key "" NX EX 60 原子写入,老版本要用 SETNX + EXPIRE 组合,否则有竞态风险
  • 空值缓存要和真实数据缓存使用相同序列化方式(如 JSON.stringify),否则反序列化可能出 undefined 导致二次穿透

布隆过滤器得和业务更新强绑定

布隆过滤器(Bloom Filter)能高效拦截 99% 以上无效 key,但它本身不自动感知数据变更。如果商品下架了,而布隆过滤器里还标记“存在”,就会误拒合法请求。

Sentinal Redis
Sentinal Redis

监控Redis服务器健康状况、内存、性能及BullMQ队列。检查队列深度、失败任务,分析慢查询并诊断问题。

下载
  • 初始化阶段,用全量 ID 扫描构建初始 filter,加载到 Redis 的 bf.reserve 结构(RedisBloom 模块)或本地 new BloomFilter()
  • 每次写 DB 成功后,同步调用 bf.add;删 DB 前,调用 bf.remove(如果支持)或清空对应 key + 重建局部 filter
  • 不推荐纯客户端布隆过滤器(如 Java 的 Guava BloomFilter),因为多实例无法共享状态,容易漏判
  • 误判率控制在 0.01 以内即可,再低会显著增加内存;用 bf.cardinality 定期检查容量,超 80% 就触发扩容或重建

RedisKey 设计要区分“存在性”和“数据内容”

很多团队把所有逻辑塞进一个 key,比如 user:123 既存用户数据,又靠它是否存在来判断用户存不存在——这会让空值缓存、布隆过滤器、DB 查询三者耦合,一环出错全崩。

  • 拆成两个 key:user:exists:123(布尔 or 空字符串,用于快速存在性判断),user:data:123(JSON 数据)
  • 布隆过滤器只校验 user:exists:* 前缀的 key,不碰 user:data:*
  • DB 更新时,先更新 user:exists:123,再更新 user:data:123;读取时,先查 exists key 或布隆过滤器,再决定是否查 data key
  • 这个分离让监控更清晰:你可以单独看 user:exists:* 的命中率,而不会被 data key 的过期策略干扰

真正难的不是加布隆过滤器,是让它的生命周期和业务数据变更节奏对齐。漏掉一次 bf.add,可能引发一小时的穿透流量;而过度保守地缓存空值,又会拖慢正常请求。这两边的阈值,得靠线上 redis-cli --stat 和业务日志里的 key 分布一起调。

相关专题

更多
常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

4869

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

4435

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

8532

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

663

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

776

6

mysql和redis怎么保证双写一致性
mysql和redis怎么保证双写一致性

确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

8822

6

redis缓存一般存些什么数据
redis缓存一般存些什么数据

redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1180

6

redis的8种数据类型有哪些
redis的8种数据类型有哪些

redis 提供 8 种数据类型:字符串(文本、数字、二进制)、哈希(键值对)、列表(有序集合)、集合(无序唯一元素)、有序集合(按分数排序)、地理空间(地理位置)、hyperloglog(估计大数据基数)和位图(位序列存储)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1396

6

redis主要作用有哪些
redis主要作用有哪些

redis 的主要作用包括:1. 缓存数据,提高访问速度;2. 充当消息队列,实现消息传递;3. 存储各种数据类型,如字符串、散列和集合;4. 管理会话信息,确保可靠性和可用性;5. 限制请求速率,防止服务器超载等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

7558

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习