一、布隆过滤器介绍

Bloom Filter是一种空间效率很高的随机数据结构,Bloom Filter可以看做是对bit-map的扩展,它的原理如下:

当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位阵列(Bit Array)中的K个点,把它们置为1,检索时我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了。

1、如果这些点有任何一个0,那么被检索元素一定不存在;

2、如果都是1,那么被检索元素可能存在;

存在这种场景:有A,B二个数,A存在,但B不存在。假如利用Bloom Filter将它们映射成K个点,但刚好AB的K个点重合。那么在检索B数据时,刚好可以看到B对应的所有标识位上全为1,但实际上B却不存。

我们以下面的例子来说明布隆过滤器: 假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8) 产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到 1 到十六亿中的八个自然数 g1, g2, ...,g8。现在我们把这八个位置的二进制全部设置为一。当我们对这一亿个 email 地址都进行这样的处理后。一个针对这些 email 地址的布隆过滤器就建成了。(见下图)

布隆过滤器(Bloom Filter)-LMLPHP

现在,让我们看看如何用布隆过滤器来检测一个可疑的电子邮件地址 Y 是否在黑名单中。我们用相同的八个随机数产生器(F1, F2, ..., F8)对这个地址产生八个信息指纹 s1,s2,...,s8,然后将这八个指纹对应到布隆过滤器的八个二进制位,分别是 t1,t2,...,t8。如果 Y 在黑名单中,显然,t1,t2,..,t8 对应的八个二进制一定是一。这样在遇到任何在黑名单中的电子邮件地址,我们都能准确地发现。

布隆过滤器决不会漏掉任何一个在黑名单中的可疑地址。但是,它有一条不足之处。也就是它有极小的可能将一个不在黑名单中的电子邮件地址判定为在黑名单中,因为有可能某个好的邮件地址正巧对应个八个都 被设置成一的二进制位。好在这种可能性很小。我们把它称为误识概率。在上面的例子中,误识概率在万分之一以下。

布隆过滤器的好处在于快速,省空间。但是有一定的误识别率。常见的补救办法是在建立一个小的白名单,存储那些可能别误判的邮件地址。

二、使用场景

主要使用场景:用来检测某个元素是否是巨量数据集合中的成员,但识别结果存在误差;

识别场景:某个元素实际不存在,但是由于前面元素在进行多个Hash时,刚好对应位为1,那么会误认为其存在,但实际不存在。

如果某个成员确实属于集合,那么Bloom Filter一定能够给出正确的判断。

三、应用举例

A、B两个文件,各存放50亿条URL,每条URL占用64个字节,内存限制是4G,让你找出A、B文件共同的URL。如果是三个甚至N个文件呢?

分析:如果允许有一定的错误率,可以使用Bloom Filter,4G内存大概可以表示为340亿bit。将其中一个文件中的URL使用Bloom Filter映射为这340亿bit,然后挨个读取另外一个文件的URL,检查是否与Bloom Filter中相同,如果是,那么该URL应当是共同的URL(注意:这种方式存在一定的错误率)

04-28 09:39