Redis过滤器那些实用小技巧,教你快速搞定不踩坑
- 问答
- 2025-12-30 12:01:15
- 3
说到Redis过滤器,这玩意儿在互联网公司里用得可太普遍了,主要就是用来解决那种“是否存在”的问题,而且是用一种特别省内存的方式,但你要是用不好,也容易掉坑里,下面这些技巧,很多都是像知乎、掘金上的技术博主,还有像阿里云、腾讯云这些官方技术文档里反复提到过的,我帮你捋一捋,保证说得明明白白。
第一招:选对类型,别一上来就用布隆过滤器
很多人一听说过滤器,脑子里蹦出来的就是布隆过滤器(Bloom Filter),但其实Redis自己就带了两种“过滤器”结构,你得看菜下饭。
-
布隆过滤器(Bloom Filter, BF):这是老大哥,也是最经典的,它的特点就是,告诉你“某个元素可能存在”或者“一定不存在”,注意这个“可能存在”,它是有一定的误判率的,这意味着,它可能会把本来不在集合里的东西,误判成存在(假阳性),但它最大的优点是极其节省空间,适合用在那些“误判了也没太大关系”的场景。
- 推荐系统去重:给用户推荐新闻或视频,就算某条内容用户可能看过但被误判成没看过,再推荐一次问题也不大,用户可能也没印象。
- 缓存穿透防护:防止有人恶意查询一个根本不存在的数据,直接打到数据库上,先用布隆过滤器挡一下,如果它说“肯定不存在”,就直接返回,保护数据库。
- 根据阿里云Redis的开发手册里提到,在数据量巨大且可接受一定误判时,BF的内存优势非常明显。
-
布谷鸟过滤器(Cuckoo Filter, CF):这是个小老弟,但本事不小,它比布隆过滤器更厉害的地方在于,它支持删除元素!而标准的布隆过滤器是不支持删除的,除此之外,它在空间利用率上通常也更有优势,那什么时候用布谷鸟呢?
- 需要动态删除的场景:你的黑名单列表是需要有时效性的,用户被封禁一天后要自动移除,这时候用布谷鸟过滤器就非常合适。
- 对空间要求极致的场景:在数据量相近时,布谷鸟过滤器往往能用更少的内存达到相同的误判率。
- 根据腾讯云中间件的技术博客分析,在需要支持删除和高负载因子(就是内存利用率很高)的情况下,CF是比BF更优的选择。
第一步千万别搞错,需要删除选布谷鸟,可以接受误判且不删除就选布隆。
第二招:参数设置是灵魂,乱设等于白搞

选好了类型,接下来最关键的就是初始化参数了,这一步要是偷懒,后面全是坑。
主要是两个参数:预期元素数量(size) 和 误判率(error rate)。
-
预期元素数量(size):这个不是你当前有多少数据,而是你预计最终会往这个过滤器里放多少数据,比如你预计你的用户黑名单最多不会超过1亿人,那你就应该设成1亿,如果你设小了,比如只设了100万,但实际你塞进去了1000万数据,那么过滤器的误判率就会急剧上升,变得几乎不可用,知乎上有个比喻很形象:这就好比给你一个小篮子,你非要塞进一头大象,结果篮子破了,什么都装不住,这个值宁可估大,也绝不能估小。
-
误判率(error rate):这个值越小,过滤器需要的内存就越大,但判断结果越精确,这个需要根据你的业务来权衡,如果是用于拦截垃圾邮件,误判率设成1%(0.01)可能也能接受,偶尔有一封垃圾邮件进收件箱问题不大,但如果是用于金融级别的风控判断,可能就需要设得更低,比如0.1%(0.001),默认值一般是0.01,你需要自己琢磨一下。
在Redis里,创建过滤器的命令大概是这样的(以布隆过滤器为例):BF.RESERVE your_filter_name 0.01 1000000,这里0.01就是误判率,1000000就是预期的元素数量,这个参数一旦设定,过滤器创建后就不能再修改了,所以必须一开始就规划好。

第三招:别忘了数据持久化这个大事
Redis的数据是放在内存里的,一重启就全没了,你辛辛苦苦构建的一个包含几亿数据的过滤器,要是服务器重启一下就没啦,那可就悲剧了,所以你必须考虑持久化问题。
Redis本身有RDB和AOF两种持久化机制,你需要确保你的Redis配置了合理的持久化策略,比如定期生成RDB快照,或者开启AOF日志,这样即使Redis重启,也能从磁盘上把数据恢复回来,包括你的过滤器。
不过这里有个小提示:布隆过滤器和布谷鸟过滤器在Redis中是以一种特殊的数据结构存储的,持久化和恢复的过程是Redis自动完成的,你不需要额外操作,你只需要关心Redis服务本身的持久化配置是否打开并且工作正常就行了,这一点在Redis官方的Modules文档中有说明。
第四招:想清楚“误判”的后果,做好兜底

只要用了布隆过滤器,你就得时刻记着:它会说谎(假阳性),你的代码逻辑不能完全相信它说的“存在”。
举个例子,你用布隆过滤器来防止缓存穿透,你的查询逻辑应该是:
- 先查过滤器:如果过滤器说“肯定不存在”,直接返回空结果,不去查数据库。
- 如果过滤器说“可能存在”,你再继续去查Redis缓存。
- 如果缓存里没有,再去查数据库。
- 查完数据库后,如果数据确实存在,要把数据塞回缓存里。
注意,在整个过程中,即使过滤器误判了(数据其实不存在,但过滤器说可能存在),最坏的结果也就是多了一次缓存查询和一次数据库查询,虽然增加了这点开销,但总比恶意请求直接打爆数据库要好得多,这就是一个良好的兜底策略,你的业务代码必须能容忍这种小概率的额外查询。
第五招:key的命名和管理要规范
当你的系统里有成百上千个过滤器时,管理它们就是个问题了,一定要给过滤器key起一个清晰、有业务含义的名字,最好加上前缀。bf:user_blacklist, cf:news_recommendation。
要明确每个过滤器的生命周期,它是永久存在的,还是过一段时间要清理的?如果需要清理,是直接删除整个key(DEL bf:user_blacklist),还是通过布谷鸟过滤器的删除功能逐个移除元素?提前规划好,避免产生一堆无人管理的“垃圾”过滤器,占用内存。
用好Redis过滤器就这几下子:先根据能不能删除选BF还是CF;然后像对待宝贝一样精心设置size和error rate;接着确保Redis开了持久化别让数据丢了;最后在代码里处理好误判,做好兜底,把这些点都注意到了,你基本上就能轻松搞定Redis过滤器,远离大部分常见的坑了。
本文由凤伟才于2025-12-30发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/71252.html
