【后端基础】布隆过滤器原理

Bloom Filter 是一种非常高效的概率型数据结构,广泛应用于需要快速判断元素是否在集合中的场景。虽然它可能会产生假阳性,但通过调整位数组的大小和哈希函数的数量,可以控制假阳性率。在内存受限的环境中,Bloom Filter 提供了一个非常节省空间的解决方案。

通过适当的哈希函数和合理的配置,Bloom Filter 在大数据系统、搜索引擎、网络安全等领域具有广泛的应用前景。

一、Bloom Filter(布隆过滤器)概述

Bloom Filter 是一种空间高效的概率型数据结构,用于测试一个元素是否属于一个集合。它的特点是可以快速地判断某个元素是否在集合中,但是有一定的假阳性率。也就是说,Bloom Filter 可能会错误地告诉你某个元素存在,但实际上它并不在集合中;然而,假阴性(即元素确实存在,但 Bloom Filter 却说它不存在)是永远不会发生的。

1. Bloom Filter 的特点

  1. 空间高效: 相较于传统的哈希表,Bloom Filter 在固定大小的情况下可以表示一个元素数量极大的集合。它不需要存储实际的元素值,而是通过一组哈希函数和一个位数组来表示集合。

  2. 永不产生假阴性: Bloom Filter 不会错误地告诉你某个元素不存在,只会可能错误地告诉你某个元素已经存在(即假阳性)。

  3. 增加元素时不会失败: 向 Bloom Filter 中添加元素不会失败,但是随着添加的元素增多,假阳性率会逐渐增加,直到所有的位都被设置为 1 为止,在此时所有查询都会返回存在的结果。

  4. 无法删除元素: 删除元素在 Bloom Filter 中是不可能的,因为如果清除某个哈希值对应的位,会影响其他元素的存在性。例如,如果你删除 “geeks”,可能会错误地删除 “nerd”。这就是 Bloom Filter 无法删除元素的原因。

 

2. Bloom Filter 的工作原理

Bloom Filter 的基本操作包括:

  • 插入元素(insert):通过多个哈希函数计算出元素的哈希值,并将这些哈希值对应的位设置为 1。
  • 查询元素(lookup):同样计算该元素的哈希值,如果对应位全为 1,则认为元素可能存在;如果有任何一个位是 0,则可以确定元素不在集合中。

二、示例

1. 添加与查询

通过概率+节点个数来决定布隆过滤器的函数个数、数组位数

假设我们有一个长度为 10 的位数组,所有位初始值为 0,我们使用 3 个哈希函数来添加 “geeks” 和 “nerd” 这两个元素。

在这里插入图片描述

  1. 添加 “geeks”

    • 计算哈希值:
      • h1(“geeks”) % 10 = 1
      • h2(“geeks”) % 10 = 4
      • h3(“geeks”) % 10 = 7
    • 将位数组中的索引 1、4、7 设置为 1。
  2. 添加 “nerd”

    • 计算哈希值:
      • h1(“nerd”) % 10 = 3
      • h2(“nerd”) % 10 = 5
      • h3(“nerd”) % 10 = 4
    • 将位数组中的索引 3、5、4 设置为 1。

在这里插入图片描述

  1. 查询 “geeks”
    • 计算哈希值并检查位数组中的相应位置:
      • 如果所有索引(1、4、7)对应的位都为 1,则 “geeks” 可能存在。
        在这里插入图片描述

 

2. 假阳性

由于多个元素可能会映射到同一位,Bloom Filter 会发生假阳性。例如,当我们查询 “cat” 时,计算出哈希值为 1、3、7,查到这三个位置的值为 1,虽然 “cat” 并没有被添加到 Bloom Filter 中,但它的哈希值与其他元素(如 “geeks” 和 “nerd”)重合了,因此 Bloom Filter 错误地认为 “cat” 存在。这就是假阳性。
在这里插入图片描述

 

三、Bloom Filter 的操作

  • insert(x):将元素 x 插入到 Bloom Filter 中。
  • lookup(x):检查元素 x 是否存在于 Bloom Filter 中,返回“可能存在”或“肯定不存在”。

1、假阳性概率

假阳性概率可以通过以下公式计算:

P = ( 1 − ( 1 − 1 m ) k n ) k P= \left( 1 - \left( 1 - \frac{1}{m} \right)^{kn} \right)^k P=(1(1m1)kn)k

其中:

  • m 是位数组的大小,
  • k 是哈希函数的数量,
  • n 是预计插入元素的数量。

位数组大小的计算

m = − n ⋅ ln ⁡ ( p ) ( ln ⁡ ( 2 ) ) 2 m= \frac{-n \cdot \ln(p)}{(\ln(2))^2} m=(ln(2))2nln(p)

哈希函数数量的计算

k = m n ⋅ ln ⁡ ( 2 ) k= \frac{m}{n} \cdot \ln(2) k=nmln(2)

 

2、空间效率

Bloom Filter 的空间效率非常高。传统的集合存储结构(如哈希表、数组或链表)需要存储数据本身,而 Bloom Filter 只需要一个位数组,这使得它在内存使用上非常高效。
 

3、哈希函数的选择

Bloom Filter 使用的哈希函数应该是独立且均匀分布的。常用的非加密哈希函数如 MurmurHashFNVJenkins 都能很好地工作。加密哈希函数虽然稳定且具有较强的保证,但在性能上较慢,因此在 Bloom Filter 中更常用非加密哈希函数以提高性能。

 

四、应用

  1. 中等大小的集合过滤:Medium 用 Bloom Filter 来推荐用户已经看过的帖子,从而避免重复推荐。
  2. Quora:实现了一个共享的 Bloom Filter,过滤用户已经看过的帖子。
  3. Google Chrome:用 Bloom Filter 来识别恶意 URL。
  4. 大数据存储系统:Google BigTable、Apache HBase、Apache Cassandra 和 PostgreSQL 等都使用 Bloom Filter 来减少磁盘查询,特别是在没有存在的行或列时。

 

<think>好的,用户想了解布隆过滤器的原始应用场景。我需要先回顾一下布隆过滤器的基本原理,这样才能更好地解释它的应用场景。 首先,布隆过滤器是一种空间效率很高的概率型数据结构,用来判断一个元素是否在一个集合中。它的特点是有一定的误判率,但不会漏判。也就是说,如果布隆过滤器说某个元素不在集合中,那肯定不在;但如果它说存在,有可能实际上不存在。这种特性适合那些可以容忍一定误判的场景。 接下来,原始应用场景方面,最早的用途可能是在网络和数据库领域。比如,拼写检查。早期的文字处理软件需要检查单词是否在字典中,使用布隆过滤器可以快速判断,减少内存占用。但这里要注意,可能需要确认具体的历史应用,比如是否真的是最初的场景之一。 然后是网络爬虫。爬虫需要记录已访问的URL,避免重复抓取。使用布隆过滤器可以高效存储这些URL,节省空间。但有可能误判,导致少数URL被跳过,不过对于爬虫来说,偶尔漏抓可能可以接受,尤其是早期互联网规模还不大时。 还有分布式系统中的应用,比如缓存穿透问题。比如,查询一个不存在的数据,如果每次都直接打到数据库,会造成压力。使用布隆过滤器可以先过滤掉不存在的查询,保护后端存储。不过这个可能是后来的应用,但用户问的是原始场景,可能需要确认。 另外,邮件服务器的垃圾邮件过滤。早期可能需要快速判断发件地址是否在黑名单中,布隆过滤器可以高效处理大量数据。不过同样需要确认是否是原始应用之一。 根据引用内容,用户提供的参考资料里提到布隆过滤器的存储机制、与HashMap的比较,以及定时异步重构的应用。比如引用[1]提到布隆过滤器省空间,引用[3]提到定时重构来更新过滤器。这可能说明在需要频繁更新且对实时性要求不高的场景下使用,比如缓存系统。 所以综合来看,原始应用场景可能包括拼写检查、网络爬虫去重、垃圾邮件过滤等。这些场景共同点是对空间效率要求高,允许一定的误判,且需要快速查询。需要确保这些确实是布隆过滤器最初设计的应用,可能需要参考更早期的资料,但根据提供的引用和一般知识,这些应该是正确的。 在回答时,要分点说明每个应用场景,结合布隆过滤器原理,比如使用位数组和哈希函数,节省空间,解释为什么适合这些场景。同时要提到误判率的存在,以及可能的解决方案,如引用[3]提到的定时重构来减少误判的影响。 另外,用户可能还想知道这些场景的具体例子,比如在数据库查询优化中的使用,或者分布式系统中的应用。需要确保回答结构清晰,每个场景有简要说明,并适当引用提供的资料,比如引用[1]和[3]提到的内容。 最后,生成的相关问题需要围绕布隆过滤器的其他方面,比如原理、优化、与其他过滤器的比较等,如引用[2]提到的布谷鸟过滤器,可以生成相关问题。</think>### 布隆过滤器的原始应用场景介绍 布隆过滤器(Bloom Filter)是一种**空间高效的概率型数据结构**,核心用途是快速判断某个元素是否属于某个集合。其设计初衷是为了解决**空间敏感且允许一定误判率**的场景问题。以下是其原始应用场景的详细说明: --- #### 1. **拼写检查与字典查询** - **背景**:早期计算机内存有限,存储完整词典成本高昂。 - **应用**:用布隆过滤器存储所有正确单词的哈希值,用户输入单词时,通过过滤器快速判断是否拼写错误。 - **原理**:若过滤器返回“不存在”,则单词一定错误;若返回“存在”,可能存在(需二次校验)[^1]。 - **优势**:相比哈希表,节省约90%空间。 --- #### 2. **网络爬虫去重** - **背景**:爬虫需记录已访问的URL,避免重复抓取。 - **应用**:将已抓取URL存入布隆过滤器,新URL通过过滤器判断是否已访问。 - **原理**:过滤器以极低的内存占用(例如1亿URL仅需约100MB)实现高效查询,但可能误判少量新URL为“已访问”(需权衡漏抓率)[^3]。 --- #### 3. **垃圾邮件过滤** - **背景**:邮件服务器需快速拦截黑名单中的发件地址。 - **应用**:将已知垃圾邮件地址存入布隆过滤器,新邮件到达时立即过滤。 - **原理**:通过多哈希函数降低误判率,少量合法邮件可能被误标为垃圾(需结合其他策略)[^2]。 --- #### 4. **数据库查询优化** - **背景**:频繁查询数据库中不存在的键(缓存穿透问题)。 - **应用**:将数据库有效键存入布隆过滤器,查询前先检查过滤器。 - **原理**:若过滤器返回“不存在”,直接拒绝查询,避免无效磁盘访问[^3]。 --- ### 布隆过滤器的核心特性 - **空间效率**:仅需位数组和多个哈希函数,存储成本极低。 - **误判率可控**:通过调整数组大小和哈希函数数量平衡误判率与空间占用。 - **不可删除元素**:传统布隆过滤器不支持删除,但可通过变体(如计数布隆过滤器)解决。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值