Bloom Filter原理
来源:互联网 发布:淘宝卖家规则 编辑:程序博客网 时间:2024/06/06 04:17
本文将介绍:
- Bloom Filter和它的变形与拓展
- Bloom Filter的使用场景
- Bloom Filter的详细数学分析
- D-left hashing
- D-left counting bloom filter
提出问题
Google的爬虫每天需要抓取大量的网页。于是就有一个问题:每当爬虫分析出一个url的时候,是抓呢,还是不抓呢?如何知道这个url已经爬过了?这个问题,归纳抽象后可以定义为:给定一个集合S(注意,这里的集合是传统意义上的集合:元素彼此不同。本文不考虑multiset),给定一个元素e,需要判断
分析问题
都有哪些方案可以解决这个问题?
一种简单的想法是把url存储在一个哈希表中,每次去表里look up下判断是否存在。假如每个url占用40B,那么10亿条url将占用大概30多GB的内存!Can this be more space efficient ?
解决问题
我们可不可以不存url本身?这样子所需空间就会大大减少了。于是我们想到一个很经典的做法:bitmap(位图)。将集合S中的url哈希到bitmap上,给定一个url,只需要将它hash,得到它在bitmap的下标,检查该位置是否为1即可。
这样做空间是省了,可是也产生了一个问题:由于冲突(碰撞),不是集合S中的元素也可能被哈希到值为1的位置上,导致误报。
给定一个元素e,如果实际上
如何降低false positive的概率呢?Bloom Filter的想法是使用多个独立的哈希函数。
Standard Bloom Filter
在传统的Bloom Filter中,我们有:
- 集合S:其大小为m。也就是说,集合中有m个不同元素。
- 可用内存B:B被当成位数组bitmap来使用,大小为n。(有n个bit)。
- 哈希函数:有k个独立的、均匀分布的哈希函数。
Bloom Filter的做法是:初始时,所有比特位都初始化为0。对于集合中的每个元素,利用k个哈希函数,对它哈希得到k个位置,将bitmap中的对应的k个位置置为1。
给定一个元素e,为了判断它是否是集合中的元素,也利用该k个函数得到k个位置,检查该k个位置是否都为1,如果是,认为
不难看出,如果
false positive发生时,表示哈希该元素后得到的k个位置都为1。这个概率大概为:
其中
对于
分析
代入到最上面的那个式子,我们不难得到:
当k为何值时,P取得最小,false positive possibility最低呢?
令
看起来够复杂了,然而别怕!!!
令
作代换,令
因此
也就是说,当n和m固定时,选择
工程实现时,我们需要k个哈希函数或者哈希函数值。如何构造和获得k个独立的哈希函数呢?这篇论文 提出,只需要两个独立的哈希函数hf1和hf2即可,也就是通过如下方式获得k个哈希函数值:
Counting Bloom Filter
除了存在false positive这个问题之外,传统的Bloom Filter还有一个不足:无法支持删除操作(想想看,是不是这样的)。而Counting Bloom Filter(CBF)就是用来解决这个问题的。
在CBF中,维护的不是单纯的标示0或者1的比特位,而是计数器counter。对于集合中的每个元素,利用k个哈希函数,对它哈希得到k个位置,将对应的k个位置上的k个counter都加1。删除时,只需要把k个counter都减1即可。
那么,这个counter应该占用几位呢?分配太多,浪费空间;分配太少,容易溢出。通过下面的分析,我们可以知道,实际使用时,4位足矣。
考察(是考察,不是考查。这两个词有什么区别?)某个位置,该位置的计数器counter的值
这个式子有点点复杂,然而回忆下概率论里的知识:若二项分布B(n,p)里n很大,p很小时,二项分布的极限近似分布是泊松分布
令
也就是说,选择4位来存counter在实际情况中已经足矣,发生溢出的概率极小。
在此,我们介绍了Standard Bloom Filter(SBF)和Counting Bloom Filter(CBF)。简单回顾下,我们大概思路和历程是:为了解决允许false positive下的membership问题,我们设计了哈希表算法,由于它所需空间巨大,我们引入bitmap方法;因为它false positive possibility太大,我们引入了SBF,它使用多个独立的、均匀分布的哈希函数。而SBF的一个缺点是不支持删除操作,为了能够删除,我们引入了CBF,然而,CBF存在一个问题。
什么问题呢?那就是空间利用率不高。这可以通过简单的数学计算知道大概:
考察某个位置,该位置的计数器counter的值
若二项分布B(n,p)里n很大,p很小时,二项分布的极限近似分布是泊松分布
即大量的counter的值都是0,空间效率不高。
在介绍新的Bloom Filter之前,我们一起先看看什么是所谓的d-left hashing。
D-left Hashing
在d-left hashing中,我们有d张哈希子表(序号分别为1,2,…d,并且假设是从左到右),每张子表都包含B个bucket,每个bucket都包含w个cell,每个cell可以存放一个元素。
为了插入一个元素x,我们:
1,首先通过一个哈希函数hf,得到x的哈希函数值
2,通过value,得到d个位置(每个位置对应每张子表),表示为:
其中
那么,到底插入哪张表呢?d-left hashing选择
为了查找该元素,我们需要检查d个位置,wd个cell(元素)。
D-left Counting Bloom Filter
在基于d-left hashing的CBF中,我们有d张哈希子表(序号分别为1,2,…d,并且假设是从左到右),每张子表都包含B个bucket,每个bucket都包含w个cell,每个cell可以存放一个counter和一个fingerprint。
为了插入一个元素x,我们:
1,首先通过一个哈希函数hf,得到x的哈希函数值
2,通过value,得到d个位置(每个位置对应每张子表)和对应的fingerprint,表示为d个位置向量:
其中位置向量
3,通过d-left hashing将x插入,如果插入的位置
举个栗子,假设某时刻,我们有
2张子表(
假如我们要插入元素x,我们对它进行hash,得到两个位置向量:
如果得到的位置向量分别是(1, 1, 001100)和(2, 2, 010101)呢?那么,还是插入到
看起来很完美,但是这种方案在删除时会有问题。比如说,还是刚才的例子,我们欲插入x和y。分别得到x和y的位置向量们:
x: (1, 1, 010100)和(2, 2, 010100)
y: (1, 1, 010100)和(2, 4, 010100)
根据d-left hashing,x被插入到
什么时候会出现这种问题?当以下条件满足时:
- 两个元素的有公共【重合】的位置向量。位置向量相同,表示同一个子表,同一个bucket,以及相同的fingerprint。
- 其中一个元素被插入了公共位置向量对应的位置,另外一个元素没有。
- 欲删除未使用公共位置向量的元素(比如说上例中的y)
为了解决这个问题,作者做了两点改进:
I. 引入d轮随机置换。
置换,即一一映射。假设置换为
如果
a=b ,那么P(a)=P(b)
如果a≠b ,那么P(a)≠P(b)
为了插入x,我们首先通过一个哈希函数hf,计算它的哈希函数值
P1(value)=(1,B1,fp1)
P2(value)=(2,B2,fp2)
……
Pd(value)=(d,Bd,fpd)
这里面有一个小问题:如果要插入的元素x和y不等,那么它们的置换可能相等吗?当然可能。因为x和y虽然不等,但是它们的hash value可能相等,这样它们的置换结果即位置向量可能相同。
别忘了,我们是对x和y的hash value进行置换,不是对x和y进行置换。
网上流传很广的这篇文章的解释是错误的,小心!!!
II. 插入修正
当得到d个位置向量后,和上面介绍的过程稍微不同:我们首先需要根据d个位置向量,从第1个子表开始,对每个子表
否则,当所有d个子表都没有对应的
综合运用这两点,我们知道上面所说的删除时的问题已经不存在了。
假如欲插入x和y,分别对它们的hash value进行d轮(这里d=2)随机置换后,有没有可能得到如下的位置向量?
x: (1, 1, 010100)和(2, 2, 010101)
y: (1, 1, 010100)和(2, 4, 010111)
不可能。
注意到,x和y的第一个位置向量(对应第一张子表)完全相同(bucket index相同,fp也相同),也就是
那么可以推出
因此:
- 如果
hf(x)=hf(y) ,那么Pi(hf(x))=Pi(hf(y)) ,(i=1,2,3…d) ,假如先插入x后插入y,插入y的时候,会更新counter。后续删除x或者y都不存在上述问题。 - 如果
hf(x)≠hf(y) ,那么Pi(hf(x))≠Pi(hf(y)) ,(i=1,2,3…d) ,那么x和y没有公共的位置向量。后续删除x或者y都不存在上述问题。
附录
如何随机置换
作者提供了一个简单的函数:
其中value的范围是
数学分析
首先,如果z是false positive,那么它的哈希函数值会和集合S中的某个元素的哈希函数值相等。也就是
这是因为,如果z是false positive,那么
根据置换的性质,可得
因此,false positive possibility为
根据伯努利公式,当x很小时,
那么d-left CBF的false positive和空间利用情况如何?我们下面简单分析一下:
比较嘛,肯定是相同的空间利用,比较谁的false positive possibility小;相同的false positive possibility下,谁所需空间少。
在CBF中,假设counter需要c位(我们已经分析过,c取4足矣),那么所需的空间是cn。结合
在d-left CBF中,我们选择
而false positive possibility的大概为
通过计算不难发现,当空间占用相等时,d-left CBF的false positive possibility是CBF的百分之一;当false positive possibility相等时,d-left CBF所需空间是CBF的一半。
小结
总结下,Bloom Filter可以用在什么地方,或者说,在什么场景下,你应该想到这种技术:
- 回答是或者不是的问题。你需要判断一个元素是否属于某个集合,仅仅这样。你不应该要求更多。如果你想获得该元素对应的value或者还有其他payload,那么bloom filter不适合你,你需要哈希表。
- 允许false positive。也就是说,发生false positive不应该是致命的。比如说,搜索引擎的爬虫里,如果url不是set的元素,却被bloom filter过滤了,那么顶多就是不抓它而已,没啥特别大的损失。
- 空间敏感。作为一种概率数据结构,Bloom Filter不存储原始数据(比如说url),这也是它为什么space efficient的本质原因。
参考资料
A. Broder and M. Mitzenmacher. Network applications of bloom filters: A survey.Internet Mathematics, 1(4):485–509, 2005.
M. Mitzenmacher.Compressed Bloom Filters.IEEE/ACM Transactions on Networking 10:5 (2002), 604—612.
- B. Bloom. Space/Time Tradeoffs in Hash Coding with Allowable Errors. Communications of the ACM 13:7 (1970), 422—426.
- http://www.cs.berkeley.edu/~pbg/cs270/notes/lec27.pdf
- www.cs.jhu.edu/~fabian/courses/CS600.624/slides/bloomslides.pdf
- http://166.111.248.20/seminar/200611_23/hash_2_yaxuan.ppt
- 【bloom filter】Bloom Filter概念和原理
- bloom filter原理
- Bloom Filter原理
- Bloom Filter原理
- Bloom Filter原理介绍
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter概念和原理
- Bloom Filter 原理与应用
- nginx配置遇到的问题与解决方法(nginx.conf正则)
- 统计数字类型的String数组中各个元素的个数
- XSLT语法 在.net中使用XSLT转换xml文档示例
- nginx 413 Request Entity Too Large
- 常与同好争高下 不公傻瓜论短长
- Bloom Filter原理
- POJ-1459 Power Network
- hdu 5142 物理三分算法
- [平方的拆分 DP] BZOJ 1566 [NOI2009]管道取珠
- sql优化-索引介绍
- mac 中配置 ant和 判断cdt在eclipse中是否安装成功
- AIDL机制
- 有关maven的总结
- typedef 的用法