news 2026/4/23 16:25:24

一文搞懂纸老虎-布隆过滤器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文搞懂纸老虎-布隆过滤器

在工程里,我们经常遇到一种很现实的需求:

我只想快速判断某个值“在不在集合里”。
最好别占太多内存,速度还要快。

如果你把所有元素都放进HashSet或数据库索引里,当然能做到“准确判断”,但代价可能是:内存贵、磁盘慢、网络更慢。尤其在一些非关系型数据库(NoSQL)或分布式系统里,“查一个根本不存在的键”,反而可能触发多机查询、磁盘寻址、甚至跨网络请求——成本很高

这时候就轮到 Bloom Filter(布隆过滤器)登场了:一种节省空间的概率型数据结构,常用于回答这个问题:

  • 这个值在不在?
    • 一定不在
    • 可能在

它的哲学很明确:
牺牲一部分“准确性”,换取更小的内存占用与更快的判断速度。


1. Bloom Filter 是什么?一句话概括

Bloom Filter 是一种空间效率极高的概率数据结构,用于集合成员查询(membership test)。

它的回答只有两种:

  1. 一定不在(No,100% 准确)
  2. 可能在(Maybe,有一定误判率)

注意这个“误判”的方向是单向的:

  • 可能把“不存在”的元素误判为“存在”(假阳性 false positive
  • 但不会把“存在”的元素误判为“不存在”(不会出现假阴性 false negative

所以你可以记成一句工程口诀:

Bloom Filter:不在是铁证,是猜测。


2. 为什么它会“误判”?(但仍然好用)

Bloom Filter 的内部结构非常朴素:

  • 一段长度为m的位数组(bit array),初始全是 0
  • k个 hash 函数

插入一个元素时发生什么?

对元素做k次 hash,得到k个位置,把这些位置的 bit 全部置为 1。

查询一个元素时发生什么?

同样 hashk次,看对应k个 bit:

  • 只要有任意一个 bit 是 0 →一定不在
  • 如果k个 bit 全是 1 →可能在

误判的根源就在于:
不同元素经过 hash 可能会把同一批 bit 位置置为 1,久而久之,某个“不存在的元素”查询时刚好命中了一组全 1 的 bit,于是被判定为“可能在”。

这就是 Bloom Filter 的“概率性”。


3. 它到底省在哪里?为什么能省很多内存?

如果你用HashSet保存大量字符串/URL/ID:

  • 不仅要存元素本身
  • 还有对象头、指针、哈希桶、装载因子等额外开销

而 Bloom Filter 只存bit

  • 每个位置 1 bit
  • 不存原始值
  • 不存指针结构
  • 不需要扩容搬迁(通常初始化后固定)

这让它在“只想拦掉大量不存在查询”的场景里非常划算。


4. 适用场景:能容忍误判的地方,它就是神器

Bloom Filter 的典型使用方式是当作“第一道门”(pre-check):

4.1 数据库/缓存:避免查不存在的键

在一些 NoSQL 或分布式 KV 存储里,查询不存在 key 的代价可能很高(磁盘、跨节点、跨机房)。

做法:

  1. 先查 Bloom Filter
  2. 如果判定“一定不在” → 直接返回,不打到存储层
  3. 如果“可能在” → 再去真正存储查(此时才付出成本)

它减少的是:大量无意义的 I/O 与网络开销

4.2 安全/风控:过滤恶意 URL(经典案例)

业界常提到:Google 曾在安全浏览(Safe Browsing)或类似系统里用 Bloom Filter 来做快速过滤:

  • 本地用 Bloom Filter 先判断某 URL 是否“可能在黑名单”
  • 若“可能在”,再进一步请求更精确的数据/校验

这样既能节省带宽,也能提高响应速度。

4.3 其他常见场景

  • 爬虫去重(先用 Bloom Filter 粗筛,减少重复抓取)
  • 日志/埋点去重(容忍少量误判)
  • 消息队列幂等预判(“可能处理过”则走更重的校验路径)

一句话:

适合“误判可以接受,但漏判不能接受”的场景。


5. Bloom Filter 的关键:好的 Hash 函数与参数选择

你提到“Bloom filter 的关键在于拥有足够优秀的 hash 函数”——非常对。

Bloom Filter 的效果由几件事共同决定:

  • m:bit array 长度(越大越不容易全被置 1)
  • n:预计插入元素数量(越多越容易冲突)
  • k:hash 函数个数(太少判定不够严,太多会把 bit 更快置满)
  • hash 函数质量:分布要均匀、碰撞要少、速度要快

工程里常见做法:

  • 选用成熟的非加密 hash(如 MurmurHash、xxHash)来保证速度与分布
  • 用“双重哈希”(double hashing)从 2 个 hash 推导出 k 个位置,减少计算成本

Bloom Filter 不要求 hash “不可逆”,而是要求快、均匀、低碰撞、可重复


6. 权衡策略:你到底在牺牲什么?

Bloom Filter 的本质是一个权衡:

  • 你换来:更低内存、更快查询、更少 I/O
  • 你付出:假阳性(误判“在”)

但注意:
误判“在”并不会直接给最终结果判死刑,因为 Bloom Filter 通常只是预过滤。它只会导致:

  • 多做一次后续查询(比如访问数据库/缓存)
  • 或进入更严格的校验流程

不会导致把真实不存在的数据当作存在直接返回(因为后面还有真实查证)。


7. 小结

Bloom Filter 的精髓可以浓缩成三句话:

  1. 它是一种节省空间的概率数据结构,用于集合成员查询
  2. “不在”一定准确,“在”可能误判
  3. 适合容忍少量误判、但不能漏判的工程场景,尤其用来减少昂贵的不存在查询
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:35:35

适用于 iPhone 和 iPad 的最佳文件管理器

如果您觉得在 iPhone 或 iPad 上管理文件很复杂,那是因为您没有使用最适合 iPhone 和 iPad 的文件管理器。与传统的 PC 或 Mac 不同,iOS/iPadOS 采用沙盒架构,这意味着应用程序通常会将数据隔离。然而,高效的文件管理对于提高工作…

作者头像 李华
网站建设 2026/4/23 2:29:26

大数据领域 Cassandra 的表设计原则

Cassandra表设计的第一性原理:从分布式本质到生产级实践 元数据框架 标题:Cassandra表设计的第一性原理:从分布式本质到生产级实践 关键词:Cassandra、分布式数据库、表设计、主键优化、数据建模、一致性哈希、时间序列 摘要:Cassandra作为高可用、高吞吐、线性扩展的分布…

作者头像 李华
网站建设 2026/4/23 11:27:20

运维系列数据库系列【仅供参考】:达梦逻辑导入使用总结

达梦逻辑导入使用总结 达梦逻辑导入使用总结 达梦逻辑导入使用总结 实例1 1>字符集:GB18030 2>是否以字节为单位:否 实例2 1>字符集:uft8 2>是否以字节为单位:否 实例3 1>字符集:uft8 2>是否以字…

作者头像 李华
网站建设 2026/4/23 12:52:41

运维系列数据库系列【仅供参考】:达梦数据库还原之指定映射路径还原

达梦数据库还原之指定映射路径还原数据库还原之指定映射路径还原摘要正文数据库还原之指定映射路径还原 摘要 本文详细介绍了在中标麒麟7操作系统上,使用达梦8数据库进行映射路径还原的过程。首先,通过RMAN关闭数据库并进行脱机备份。接着,…

作者头像 李华
网站建设 2026/4/23 12:46:51

【go语言 | 第5篇】channel——多个goroutine之间通信

文章目录channel的定义和使用channel——有缓冲和无缓冲同步1. 无缓冲的channel2. 有缓冲的channelchannel——关闭channelchannel 与 rangechannel 与 selectchannel的定义和使用 channel 用于多个 goroutine 之间的通信。 package mainimport "fmt"func main() {…

作者头像 李华
网站建设 2026/4/20 14:51:02

基于SpringBoot的医院HIS信息系统

医院HIS信息系统课题背景 医院HIS(Hospital Information System)信息系统是医疗信息化建设的核心组成部分,旨在通过数字化手段整合医院业务流程,提升医疗服务质量与管理效率。随着医疗行业的快速发展,传统手工管理模式…

作者头像 李华