布隆过滤器的“不存在”判断绝对可靠,RBloomFilter.contains()返回false可直接返回404;其分布式实现共享Redis位数组,避免多实例不同步;误判率可控且不影响穿透防护,但需注意与空值缓存的写入顺序及预估容量。

布隆过滤器的“不存在”判断是绝对可靠的
缓存穿透的本质,是大量请求查询根本不存在的 key(比如无效商品 ID、伪造用户 token),导致请求全部绕过缓存直击数据库。而 RBloomFilter.contains() 的设计决定了:只要返回 false,这个元素就**一定没被添加过**——这个结论不依赖哈希碰撞概率,是位数组状态的确定性推导。所以你在请求入口用它拦截,false 路径可以直接返回 404 或空响应,数据库连连接都不用建。
Redisson 的 RBloomFilter 是分布式的,不是单机内存结构
很多初学者误以为布隆过滤器必须在应用启动时把全量数据 add() 一遍,结果发现扩容困难、初始化慢、多实例间不同步。Redisson 的 RBloomFilter 实际封装的是 RedisBloom 模块的 BF.ADD/BF.EXISTS 命令,所有节点共享同一份位数组。这意味着:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 新增商品时调用一次
rbloomFilter.add("goods:123456"),集群所有节点立刻生效 - 无需在每个 Spring Boot 实例里维护本地副本,避免数据不一致
- 底层自动处理 Redis 连接、序列化、重试,你只管用
contains()
误判率可控,且对防护目标无实质影响
布隆过滤器会返回假阳性(true 但实际不存在),但这个“误判”恰恰不影响缓存穿透防护逻辑:
- 当
contains()返回true,你照常走查缓存 → 查 DB 流程,最多多一次无效 DB 查询,和穿透发生时的代价相当 - 真正要防的是
false被错判成true——但布隆过滤器**永远不会这样错判**;它只会把true错成true(即误判),或false判对 - 通过公式调整
m(位数组长度)和k(哈希函数数),能把误判率压到 0.1% 甚至更低,1 亿数据也只占约 114MB 内存
和空值缓存组合使用时,注意写入顺序与生命周期
单纯靠布隆过滤器不能解决“刚写入数据库但还没进布隆过滤器”的窗口期问题。生产中通常组合空值缓存(SET goods:999999 "" EX 60),但必须注意:
- 空值缓存要在 DB 写入成功后、布隆过滤器
add()之前写入,否则可能漏掉新数据 - 布隆过滤器一旦
add()就不可逆,但空值缓存有过期时间,两者语义不同,不能互相替代 - Redisson 的
RBloomFilter不支持删除,所以别试图用它“清理”已下架商品——该场景应靠业务层兜底或换用支持删除的 Cuckoo Filter
m 和哈希函数数 k 必须在创建 RBloomFilter 时就定死,后续无法动态调整——所以预估数据规模要留余量,别等上线后才发现误判率飙升。

















