布隆过滤器简介

0. 起因

以前写爬虫的时候用过布隆过滤器(Bloom filter)作为判断和去重,今天在看RPC代码的时候发现也有布隆过滤器的身影。因为之前了解过,看到名字的瞬间就明了作者想要做什么,虽然细节记不清了。因此在这里做个记录,后面如果需要扣细节,心里懂得了原理看起来也方便。

1. 什么是布隆过滤器?

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的一个可以高效的判断出给定元素“肯定不存在”或者“可能已经存在”的概率型数据结构,这个高效不仅体现在时间上,也体现在内存上。
基本的布隆过滤器支持判断和添加这两个操作,但是不支持删除。但是经过扩展,布隆过滤器也可以实现删除,例如counting filter。
对于判断操作,如果返回假则可以说明给定元素肯定不存在;而如果返回真,则只能说给定元素有可能已经存在了。

2. 应用场景

布隆过滤器一般用于去除一些不必要的检索操作,特别是当这种检索相当耗时的时候。例如,有一个很长的链表,如果检索一个不存在的元素,常规操作需要遍历整个链表。虽然可以结合红黑树等数据结构减少减速的数量,但随着元素数量的增减,时间也会越来越长。但是如果使用了布隆过滤器,就可以在相对固定的时间内知道某个元素不存在,免去了多于的耗时。

3. 原理

布隆过滤器的基本思想是哈希函数,对于一个良好的哈希函数,任意两个不同的对象的哈希值基本是不一样。
其算法如下:

  1. 首先选取k个hash函数,n可以是除0外的任意正整数,每个函数可以把key散列成为1个整数;
  2. 开辟个数组空间,以比特位(bit)为单位,每个位都初始化为0;
  3. 某个元素加入集合时,用选取的k个hash函数计算分别计算出k个哈希值应该都小于数组长度;
  4. 判断某个key是否在集合时,查询第三部计算出的哈希值所对应的数组元素是否为1,如果存在至少一个哈希值对应的元素为0,则元素不存在;如果全部哈希值对应的元素都为1,则该元素可能已经存在;
  5. 添加某个元素的时候,只需要将哈希值对应的数组元素都设置为1即可。

例如下面这个例子:
在内存中开辟了一片连续的数组空间,并使用三个不同的哈希函数对元素进行哈希操作。如图1所以,当布隆过滤其中已经存在a, b, c, d, e, f,这几个元素的情况下,这时,需要判断元素1234567890qwer是否已经存在,三个哈希函数得到的哈希值指向的数组元素都已经被设置成1,虽然此时1234567890qwer肯定不存在,但是布隆过滤器返回的结果是元素已经存在,因此布隆过滤器存在一定误判的可能。
图一 1 布隆过滤器误判

图1 布隆过滤器误判

而图2中,对于n元素,三个哈希函数中只有一个哈希函数得出的结果指向的数组元素中为0,但这足以肯定的得出n不存在这个结论。
图2 布隆过滤器可以肯定元素不存在

图2 布隆过滤器可以肯定元素不存在

4. 哈希函数的数量和数组长度选择

既然是概率型数据结构,那么对于参数的选择肯定有一套对应的数学公式,布隆过滤器中涉及的哈希函数数量k,数组长度m,元素数量n以及误报率p的公式如图3所示,通过下面的公式,可以得到比较合理的参数:
图3 布隆过滤器公式

图3 布隆过滤器参数选择公式

至于公式怎么推导出来的,这里(wo)就(ye)不(bu)介(zhi)绍(dao)了。

公众号二维码

首发于个人微信公众号TensorBoy。微信扫描上方二维码或者微信搜索TensorBoy并关注,及时获取更多最新文章!
C++ | Python | Linux | 原理 | 源码,有一起玩耍的么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值