浅析布隆过滤器

简介: 布隆过滤器 (Bloom Filter) 是 1970 年由布隆提出的。它可以检索一个元素是否存在于集合中。它的优点是空间效率高,查询时间极快,缺点是有一定的误判率,而且删除困难。

最后更新时间 2021-10-05.

布隆过滤器 (Bloom Filter) 是 1970 年由布隆提出的。它可以检索一个元素是否存在于集合中。它的优点是空间效率高,查询时间极快,缺点是有一定的误判率,而且删除困难。

1. 背景

编程中,经常会有判断一个元素是否存在一个集合中:

  • 网络爬虫程序:判断一个地址是否被访问过;
  • 文字处理软件:检查单词的拼写 (也就是判断它是否存在词典里);
  • 电子邮件黑名单。

其中,最直接的办法是,将集合所有元素存储起来,判断时与集合中的元素比较即可。

一般来说会使用哈希表来存储集合,速度快效率高,可以在 O(1) 的时间复杂度返回结果。但是哈希表本身由于负载因子的存在,不可能用满,也就是会有空间浪费的问题,对于网络爬虫来说,可能会处理几十亿的 URL 链接集合,哈希表占据的内存大小是非常可观的。

2. 原理

布隆过滤器,实际上是由一个很长的 bit 向量和一系列的随机映射函数构成的。

它的原理是,当集合新增元素时,通过 K 个哈希函数将该元素映射为多个哈希值,并对每个生成的哈希值对应的 bit 位置为 1。

举个例子,针对 张三 使用 3 个哈希函数,生成了 3 个哈希值 1、5、7,设置对应的 bit 位后如下图所示:

^-------------------------------^
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---------------------------------
| 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
v-------------------------------v

同样,也对 李四 使用 3 个哈希函数,生成了 3 个哈希值 2、3、7:

^-------------------------------^
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---------------------------------
| 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 |
v-------------------------------v

要判断 钱五 是不是在集合里,计算哈希值 5、6、7,显然不在。

特别注意的是,对张三、李四、钱五都生成了相同的哈希值 7,所以布隆过滤器是会误判的。

以检测一个可疑电子邮件地址是否存在黑名单为例:

布隆过滤器绝对不会漏掉任何一个存在黑名单的电子邮箱地址,但它可能将不在黑名单中的电子邮箱误判。补救方法是建立一个白名单,将可能误判的电子邮箱地址保存起来。

3. 优点

  1. 存储空间,插入时间,查询时间均为常数 O(k);
  2. K 个哈希函数之间并无关联,方便硬件并行实现;
  3. 不需要存储原始元素,有利于数据保密。

4. 缺点

  1. 存在一定的误判率:这个很容易理解,因为不能保证不同元素通过哈希函数的计算后,得到不同的哈希值;
  2. 删除元素困难:这个也不难理解,多个元素计算后,可能会共用同一个 1,如果删除元素将其置 0,会导致其他元素出错。

引用维基百科的解释:

一般情况下不能从布隆过滤器中删除元素。
我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加 1,这样删除元素时将计数器减掉就可以了。
然而要保证安全地删除元素并非如此简单。
首先我们必须保证删除的元素的确在布隆过滤器里面。
这一点单凭这个过滤器是无法保证的。
另外计数器回绕也会造成问题。

False positives 概率推导:https://www.cnblogs.com/liyulong1982/p/6013002.html

关于如何选择哈希函数个数和布隆过滤器长度,有一个公式,可以根据业务情况,在误断率和内存空间权衡:

m = - (n * ln p) / (ln 2) ^ 2, k = m * ln * 2 / n

其中,k 为哈希函数个数,m 为布隆过滤器长度,n 为插入的元素个数,p 为误断率。

5. 实现

网上有个 Golang 版,有时间的话写个 PHP 版,不过 PHP 处理二进制真心不爽……


文章来源于本人博客,发布于 2018-06-02,原文链接:https://imlht.com/archives/150/

目录
相关文章
|
4月前
|
算法
哈希函数堂兄弟 “布隆过滤器”
哈希函数堂兄弟 “布隆过滤器”
|
16天前
|
存储 缓存 NoSQL
详解布隆过滤器原理与实现
详解布隆过滤器原理与实现
|
3月前
|
算法 容器
布隆过滤器
布隆过滤器
|
4月前
|
算法 NoSQL Redis
一文搞懂布隆过滤器(BloomFilter)
一文搞懂布隆过滤器(BloomFilter)
295 0
|
4月前
|
存储 数据采集 缓存
解密布隆过滤器:数据领域的魔法阵
解密布隆过滤器:数据领域的魔法阵
69 0
|
4月前
|
存储 NoSQL Java
什么是布隆过滤器?如何实现布隆过滤器?
什么是布隆过滤器?如何实现布隆过滤器?
110 0
|
4月前
|
存储 算法 Linux
C++ 哈希的应用【布隆过滤器】
C++ 哈希的应用【布隆过滤器】
61 0
|
11月前
|
存储 数据采集 缓存
布隆过滤器:原理与应用
在日常生活和工作中,我们经常需要处理海量的数据,筛选出有用的信息。这个时候,布隆过滤器(Bloom Filter)就派上了用场。
172 1
布隆过滤器:原理与应用
|
11月前
|
存储 算法 数据库
哈希的应用:布隆过滤器(C++实现)
哈希的应用:布隆过滤器(C++实现)
67 0
|
存储 人工智能 算法
哈希的应用——布隆过滤器
布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。