news 2026/2/16 6:14:18

一文讲透布隆过滤器实现原理及应用场景总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文讲透布隆过滤器实现原理及应用场景总结

布隆过滤器的工作原理

布隆过滤器的工作原理基于三个核心要素:

1. 一个大的位数组(Bit Array)

这是布隆过滤器的存储主体。它是一个长度为m的数组,每个位置只存储一个比特(0或1)。初始时,所有位都是0

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0](一个长度为12的位数组示例)

2. 一组哈希函数(Hash Functions)

你需要准备k个不同的、相互独立的哈希函数(比如h1(x),h2(x),h3(x))。这些函数的作用是:将任意输入的字符串(或其他数据)映射到位数组的某个下标位置上

关键点:好的哈希函数应该尽可能均匀地把输入散列到整个位数组上

3. 两种基本操作:添加(Add)和查询(Exists)

3.1.A. 添加元素(例如,把客人“张三”加入名单)

1. 将“张三”分别通过k个哈希函数进行计算

  • h1("张三")-> 返回位置 2
  • h2("张三("张三")-> 返回位置 5
  • h3("张三")-> 返回位置 10

2. 将位数组中这 k 个位置个位置(2, 5, 10)的值都设置为1

操作后的位数组变为:[0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0]

接着,你再添加“李四”:

  • h1("李四")-> 位置 2 (巧合,与张三相同)
  • h2("李四")-> 位置 7
  • h3("李四")-> 位置 位置 11

再次将位置2, 7, 11设为1。注意,位置2原本就是1了,保持不变。 操作后的位数组变为:[0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1]

3.2.B. 查询元素(例如,查询“王五”是否来过)

1. 将“王五”同样通过那k个哈希函数进行计算。

  • h1("王五")-> 返回位置 3
  • h2("王五")-> 返回位置 5
  • h3("王五")-> 返回位置 11

2. 去检查位数组中这k个位置(3, 5, 11)的值。

  • 如果其中有任何一个位置的值为0那么可以肯定地说,“王五”绝对没有被加入过过滤器(因为如果他来过,这些位置肯定都被设为1了)
  • 如果所有位置的值都是1那么布隆过滤器会告诉你,“王五”可能存在(可能会存在误判)

在上面的例子中,位置3是0,所以我们可以确信地回答:“王五没来过”

现在,我们来查一个不存在的“赵六”:

  • h1("赵六")-> 位置 2
  • h2("赵六")-> 位置 5
  • h3("赵六")-> 位置 10

我们发现位置2、5、10全都是1!这时布隆过滤器会错误地告诉我们:“赵六可能存在”,这就是所谓的误判(False Positive)

3.3. 为什么会产生误判?

误判的根本原因是:哈希碰撞

  • 不同的元素(如“张三”和“李四”)可能会被哈希到同一个位置(比如位置2)
  • 当我们查询一个从未加入过的元素“赵六”时,它被哈希到的所有位置 (2, 5, 10) 恰好都被之前加入的其他元素(“张三”把2,5,10都占了)给设置成了1
  • 布隆过滤器看到这些位都是1,就“想当然”地认为这个元素之前已经被添加过了

3.4. 如何减少误判率?

误判是无法完全消除的,但可以通过调整参数将其控制在一个很低的水平,主要参数有三个:

  1. 位数组长度(m)m越大,可供标记的位置越多,发生哈希碰撞的概率就越低;但需要的空间也越大。
  2. 哈希函数的数量(k)k太少,会导致对每个元素的标识不够独特;k太多,又会很快把位数组填满,增加碰撞概率。需要一个最优值
  3. 已插入元素的数量(n):随着插入的元素越来越多,位数组里1的比例越来越高,误判率也会随之上升

有一个著名的公式可以用来估算最优的k值和预期的误判率p

从公式可以看出,要想获得较低的误判率,位数组大小m需要与插入元素数量n成正比例关系通常在实践中,我们会预设一个期望的误判率和最大数据量,然后反推出需要多大的m

3.5 优缺点总结

优点:

  1. 空间效率极高:相比于存储原始数据(如哈希表),它只使用比特位,非常省内存
  2. 查询时间复杂度为O(k):仅需进行k次哈希计算和位查找,速度极快,k是常数

缺点:

  1. 存在误判率:这是最主要的缺点,只能回答“必然不存在”和“可能存在”
  2. 不能删除元素:因为将一个位置由1置0可能会影响到其他也被映射到该位置的元素;
    不过有一种变体计数布隆过滤器(Counting Bloom Filter,它使用计数器而不是单个比特,可以支持删除操作,但会占用更多空间

布隆过滤器常见应用场景

01-缓存穿透问题

这是布隆过滤器最常用的场景,在查询数据库前,先用布隆过滤器判断数据是否存在。如果布隆过滤器说不存在,就直接返回,避免了对数据库的无意义查询。解决缓存穿透问题常用(老生常谈)

02-网络与安全方面

1.网页爬虫的 URL 去重

  • 背景:网络爬虫需要避免重复抓取相同的 URL,既浪费资源,又可能给对方服务器造成压力。
  • 问题: 互联网上的 URL 数量极其庞大,使用传统的哈希表存储在内存中会占用巨大空间。
  • 解决方案:使用一个布隆过滤器来记录所有已经爬取过的 URL
  • 工作流程:
    1.每当爬虫解析出一个新的待爬取 URL。
    2.先查询布隆过滤器:“这个 URL 我可能爬过吗?”
    3.如果返回“肯定没爬过”,那么就放心地去爬取,并将该 URL 加入过滤器。
    4.如果返回“可能爬过”,则可以直接丢弃或放入一个优先级很低的队列中进行二次确认(例如再用一个小型的精确集合检查一次)
  • 效果:用极小的内存代价实现了海量 URL 的去重。虽然可能有极少数的 URL 因误判而被遗漏,但对于大多数搜索引擎来说,这是完全可以接受的代价

2.恶意网站/垃圾邮件检测

  • 背景: 浏览器、防火墙或邮件服务器需要快速判断一个网址/发件人是否是恶意的
  • 解决方案: 维护一个已知的恶意网址/邮箱黑名单 的布隆过滤器
  • 工作流程:
    1.用户点击一个链接或收到一封邮件。
    2.客户端迅速用布隆过滤器检查该网址/邮箱地址。
    3.如果布隆过滤器说“肯定是安全的”(即不在黑名单中),则立即放行,用户体验无延迟。
    4.如果布隆过滤器说“可能是恶意的”,此时再启动更复杂、更耗时的精确查询(例如到云端的安全数据库进行核实)。
  • 效果:为绝大多数安全的访问提供了“零延迟”的体验,只在少数可疑情况下才付出较高的验证成本

03-推荐系统与内容治理

1.已读内容去重 (如新闻推送、社交媒体)

  • 背景:在今日头条、微博等信息流产品中,需要避免给用户重复推荐他们已经看过的内容
  • 解决方案:为每个用户维护一个布隆过滤器,里面存放他们近期已浏览内容的ID
  • 效果:当从内容池中选择内容推送给用户时,可以先通过布隆过滤器过滤掉那些用户“很可能”已经看过的内容,提升用户体验。即使偶尔误判了一个用户没看过的内容,也只是少推荐一条而已,影响可控

2.防止缓存击穿 (一种特殊的缓存穿透)

  • 背景: 缓存击穿是指某个热点key过期,此时有大量请求并发涌向数据库,导致数据库瞬间压力过大
  • 解决方案: 使用布隆过滤器 + 互斥锁
  • 工作流程:
    1. 将所有可能成为热点的 key 预先加入到布隆过滤器中。
    2. 当一个请求查询缓存未命中时,先去布隆过滤器检查。
    3. 如果布隆过滤器说“肯定不存在”(意味着这不是一个合法的热点key),直接返回空
    4. 如果说“可能存在”,才允许他去争夺一个互斥锁,然后只有一个请求可以去数据库加载数据并回填缓存。
  • 效果:布隆过滤器在这里起到了第一道屏障的作用,将大量的非法请求和一部分非热点数据的请求直接挡在数据库之外,让竞争锁的请求数大大减少

04-密码校验

有些系统会维护一个“弱密码”列表,禁止用户设置。
在注册或修改密码时,可以用布隆过滤器快速判断用户设置的密码是否“绝对不是”弱密码。如果是,则直接通过;如果“可能是”,再进行精确匹配。这样可以避免每次都在庞大的弱密码库里做字符串比对

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 1:21:58

软件工程导论实验报告——商品管理系统(黑龙江大学)

面向对象分析与设计实验一 软件需求分析1.1 业务需求描述该系统在商家和顾客之间搭建了一个桥梁,需要实现商家对商品的售卖和修改,以及顾客的购买商品需求,期间还需要实现对商品和商家的管理以及对顾客的评估和管理。系统本身还需要对商家和顾…

作者头像 李华
网站建设 2026/2/15 3:28:47

不能头脑简单地搞“凡是”:凡是偶数2n(n的变域是N)必∈N

不能头脑简单地搞“凡是”:凡是偶数2n(n的变域是N)必∈N黄小宁设一游击队有无穷多个队员,队中各人都配有一枪。各枪都有枪号,将配有 n 号枪的人记为 n 号人,队中枪与人已一一配对: n 号人↔n 号…

作者头像 李华
网站建设 2026/2/7 0:30:10

Parquet Reading 加速

参考链接 https://zhuanlan.zhihu.com/p/675905983

作者头像 李华
网站建设 2026/2/6 14:23:49

从“写代码”到“定义问题”——AI 时代程序员的生存宣言

本文原创公开首发于 CSDN 如需转载,请在文首注明出处与作者:yu779 从“写代码”到“定义问题”——AI 时代程序员的生存宣言 > “AI 一天写的代码,比我一周都多,那我还有存在的意义吗?” > 带着这个灵魂拷问&am…

作者头像 李华
网站建设 2026/2/8 1:42:51

iPhone运行Android完整指南:Project Sandcastle终极教程

iPhone运行Android完整指南:Project Sandcastle终极教程 【免费下载链接】projectsandcastle Supporting tools for Android/Linux on the iPhone 项目地址: https://gitcode.com/gh_mirrors/pr/projectsandcastle 在iPhone上运行Android系统,这听…

作者头像 李华
网站建设 2026/2/9 11:40:32

微信遥控Mac:WeChatPlugin远程控制终极指南

微信遥控Mac:WeChatPlugin远程控制终极指南 【免费下载链接】WeChatPlugin-MacOS 微信小助手 项目地址: https://gitcode.com/gh_mirrors/we/WeChatPlugin-MacOS 你是否曾经想过,躺在沙发上就能控制远在书房里的Mac电脑?或者在外出时突…

作者头像 李华