Bloom Filter——大规模数据处理利器

Bloom Filter 是由 Bloom 1970 年提出的一种多哈希函数映射的快速查找算法。通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求 100% 正确的场合。

 

. 实例

为了说明 Bloom Filter 存在的重要意义,举一个实例:

假设要你写一个网络蜘蛛( web crawler )。由于网络间的链接错综复杂,蜘蛛在网络间爬行很可能会形成 。为了避免形成 ,就需要知道蜘蛛已经访问过那些 URL 。给一个 URL ,怎样知道蜘蛛是否已经访问过呢?稍微想想,就会有如下几种方案:

1. 将访问过的 URL 保存到数据库。

2. HashSet 将访问过的 URL 保存起来。那只需接近 O(1) 的代价就可以查到一个 URL 是否被访问过了。

3. URL 经过 MD5 SHA-1 等单向哈希后再保存到 HashSet 或数据库。

4. Bit-Map 方法。建立一个 BitSet ,将每个 URL 经过一个哈希函数映射到某一位。

方法 1~3 都是将访问过的 URL 完整保存,方法 4 则只标记 URL 的一个映射位。

 

以上方法在数据量较小的情况下都能完美解决问题,但是当数据量变得非常庞大时问题就来了。

方法 1 的缺点:数据量变得非常庞大后关系型数据库查询的效率会变得很低。而且每来一个 URL 就启动一次数据库查询是不是太小题大做了?

方法 2 的缺点:太消耗内存。随着 URL 的增多,占用的内存会越来越多。就算只有 1 亿个 URL ,每个 URL 只算 50 个字符,就需要 5GB 内存。

方法 3 :由于字符串经过 MD5 处理后的信息摘要长度只有 128Bit SHA-1 处理后也只有 160Bit ,因此方法 3 比方法 2 节省了好几倍的内存。

方法 4 消耗内存是相对较少的,但缺点是单一哈希函数发生冲突的概率太高。还记得数据结构课上学过的 Hash 表冲突的各种解决方法么?若要降低冲突发生的概率到 1% ,就要将 BitSet 的长度设置为 URL 个数的 100 倍。

 

. Bloom Filter 的算法

   废话说到这里,下面引入本篇的主角 ——Bloom Filter 。其实上面方法 4 的思想已经很接近 Bloom Filter 了。方法四的致命缺点是冲突概率高,为了降低冲突的概念, Bloom Filter 使用了多个哈希函数,而不是一个。

   Bloom Filter 算法如下:

   创建一个 m BitSet ,先将所有位初始化为 0 ,然后选择 k 个不同的哈希函数。第 i 个哈希函数对字符串 str 哈希的结果记为 h i str ),且 h i str )的范围是 0 m-1

 

(1) 加入字符串过程

 

下面是每个字符串处理的过程,首先是将字符串 str“ 记录 BitSet 中的过程:

对于字符串 str ,分别计算 h 1 str ), h 2 str ……h k str )。然后将 BitSet 的第 h 1 str )、 h 2 str ……h k str )位设为 1

1.Bloom Filter 加入字符串过程

很简单吧?这样就将字符串 str 映射到 BitSet 中的 k 个二进制位了。

 

(2) 检查字符串是否存在的过程

 

下面是检查字符串 str 是否被 BitSet 记录过的过程:

对于字符串 str ,分别计算 h 1 str ), h 2 str ……h k str )。然后检查 BitSet 的第 h 1 str )、 h 2 str ……h k str )位是否为 1 ,若其中任何一位不为 1 则可以判定 str 一定没有被记录过。若全部位都是 1 ,则 认为 字符串 str 存在。

 

若一个字符串对应的 Bit 不全为 1 ,则可以肯定该字符串一定没有被 Bloom Filter 记录过。(这是显然的,因为字符串被记录过,其对应的二进制位肯定全部被设为 1 了)

但是若一个字符串对应的 Bit 全为 1 ,实际上是不能 100% 的肯定该字符串被 Bloom Filter 记录过的。(因为有可能该字符串的所有位都刚好是被其他字符串所对应)这种将该字符串划分错的情况,称为 false positive

 

(3) 删除字符串过程

   字符串加入了就被不能删除了,因为删除会影响到其他字符串。实在需要删除字符串的可以使用 Counting bloom filter(CBF) ,这是一种基本 Bloom Filter 的变体, CBF 将基本 Bloom Filter 每一个 Bit 改为一个计数器,这样就可以实现删除字符串的功能了。

 

Bloom Filter 跟单哈希函数 Bit-Map 不同之处在于: Bloom Filter 使用了 k 个哈希函数,每个字符串跟 k bit 对应。从而降低了冲突的概率。

 

. Bloom Filter 参数选择

  

   (1) 哈希函数选择

   哈希函数的选择对性能的影响应该是很大的,一个好的哈希函数要能近似等概率的将字符串映射到各个 Bit 。选择 k 个不同的哈希函数比较麻烦,一种简单的方法是选择一个哈希函数,然后送入 k 个不同的参数。

   (2)Bit 数组大小选择

   哈希函数个数 k 、位数组大小 m 、加入的字符串数量 n 的关系可以参考参考文献 1 。该文献证明了对于给定的 m n ,当 k = ln(2) * m/n 时出错的概率是最小的。

   同时该文献还给出特定的 k m n 的出错概率。例如:根据参考文献 1 ,哈希函数个数 k 10 ,位数组大小 m 设为字符串个数 n 20 倍时, false positive 发生的概率是 0.0000889 ,这个概率基本能满足网络爬虫的需求了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值