高并发场景下,解决 Redis 缓存穿透最可控的手段是在缓存查询前部署布隆过滤器拦截非法 key。它适用于 key 空间明确且允许少量误判的场景,但需注意布隆过滤器不支持删除且存在误判率。
先说结论:布隆过滤器是解决缓存穿透最可控的手段,前提是它被正确集成到请求入口且不被绕过。
- 适合:key 空间可预估、允许极低误判率的业务。
- 优先做:部署在 Redis 查询之前,拦截一定不存在的 key。
- 再验证:监控数据库 QPS 下降情况及过滤器内存占用。
命令速用版
RedisBloom 模块提供原生命令支持,可直接在 Redis 客户端操作布隆过滤器。
# 创建过滤器(误判率 0.01,容量 1000)
BF.RESERVE myBloom 0.01 1000
# 添加元素
BF.ADD myBloom user:1001
# 检查元素是否存在(返回 1 可能存在,0 一定不存在)
BF.EXISTS myBloom user:1001为什么会这样
缓存穿透是指查询不存在的数据导致请求直达数据库,布隆过滤器通过位数组和哈希函数判断元素一定不存在或可能存在。
正常缓存流程中,Redis 未命中会查询数据库,若数据库也无数据,攻击者可通过随机 key 持续打穿缓存层。布隆过滤器本质是内存中的概率型集合,只能回答“这个 key 可能存在”或“一定不存在”。它必须部署在缓存查询之前,否则就失去拦截意义。正确链路为请求先经过布隆过滤器,若判定“一定不存在”则直接返回,不再查询 Redis 和 DB。
分步处理
实施布隆过滤器需按步骤完成模块安装、数据初始化和链路集成,每一步都有明确的检查点。
1. 安装 RedisBloom 模块
使用 Docker 一键安装或源码编译安装 RedisBloom 模块,验证安装后确保 BF 命令可用。
2. 初始化全量合法 key
初始化时要把所有合法 user_id、product_id 全量哈希进去,增量数据需同步更新布隆结构。若你有 1 亿个合法用户 ID,要求误判率≤0.1%,布隆过滤器至少需要约 1.4 GB 内存,生产环境必须按真实数据量预估。
3. 请求链路插入过滤器
代码逻辑中,在查询 Redis 前调用 BF.EXISTS。若返回 0,直接返回空结果;若返回 1,继续查询 Redis 和 DB。
4. 处理误判和删除问题
布隆过滤器不支持删除,被软删除的 ID 仍会“存在”于过滤器中,需配合逻辑删除 + TTL 缓存兜底。别用 String 拼接做简易布隆,它没有抗碰撞设计,攻击者可轻易构造哈希冲突绕过。
怎么验证是否生效
验证生效需观察数据库负载变化及过滤器内存状态,确认拦截逻辑未被绕过。
1. 监控数据库 QPS
对比接入前后数据库查询量,有实践案例显示接入后数据库查询量显著下降,响应时间缩短。
2. 检查过滤器内存
使用 Redis MEMORY USAGE 命令检查布隆过滤器占用内存,确保未超出预估容量。
3. 模拟非法请求
发送大量不存在的 key 请求,确认请求在布隆过滤器层被拦截,未到达数据库层。
常见坑
实施过程中需注意容量规划、删除限制和前置位置,避免业务报错或拦截失效。
- 误判率与容量绑定:误判率和容量是布隆过滤器的一体两面,改一个必动另一个。如果用太小的 bitmap,误判率飙升,会导致大量合法请求被误杀,业务直接报错。
- 不支持删除:标准布隆过滤器不支持删除元素,用户注销等场景需配合逻辑删除处理。
- 必须前置:若部署在 Redis 未命中之后,此时穿透已经发生,拦截失去意义。
- 需搭配参数校验:布隆过滤器防的是“不存在的 key”,但挡不住“存在却非法的请求”,如 user_id = -1,需在布隆前加一层基础校验。
常见问题
布隆过滤器支持删除元素吗?
标准布隆过滤器不支持删除元素,因为多个元素可能映射到位数组的同一位置,删除会影响其他元素判断。
空值缓存能替代布隆过滤器吗?
空值缓存对正常业务有效,但面对攻击者用随机 key 疯狂刷接口时,会迅速堆积海量无效 key 吃光 Redis 内存,无法区分“真不存在”和“暂时没数据”。
误判率设置多少合适?
生产环境必须按真实数据量预估,不能拍脑袋。误判率设置越小,使用的内存就越多,需根据业务容忍度平衡。
参考来源
- Redis 如何彻底解决缓存穿透问题_通过布隆过滤器拦截非法请求
- Redis 布隆过滤器实战:从原理到代码实现缓存穿透防线
- 布隆过滤器原理与 Redis 防穿透实战
- Redis 应用 - 布隆过滤器:高效解决海量数据过滤难题
- Redis 缓存穿透,缓存击穿,缓存雪崩的解决方案与布隆过滤器
- redis 缓存穿透穿透解决方案 - 布隆过滤器
- redis 使用布隆过滤器解决缓存穿透 - 面试宝典
- 技术分享 | 缓存穿透 - Redis Module 之布隆过滤器
- java 布隆过滤器解决 redis 缓存穿透_redis 缓存怎么过滤数据
- Redis_缓存雪崩、缓存穿透、基于布隆过滤器解决缓存穿透的问题、缓存击穿、基于缓存击穿工作实际案例