1 Overview
Bloom filter最早由 Burton Howard Bloom提出,是一种用于判断成员是否存在于某个集合中的数据结构。 Bloom filter的判断基于概率论:
- 如果某个成员存在于集合中,那么Bloom filter不会返回假(即不存在),也就是说false negative是不可能的。
- 如果某个成员实际上不存在于集合中,Bloom filter可能返回真(即存在),这种情况被称为false positive。
Bloom filter通常被实现为一个包含 m
位的位数组(bit array),所有位的初始值都为0。 Bloom filter支持以下两种类型的操作:
- add。将成员添加到Bloom filter中。以该成员为参数调用 k
个索引函数(index functions),得到 k
个位数组的索引值,取值范围是 [0, m), 然后将位数组的对应位设置为1。
- query。判断某个成员是否已经添加到Bloom filter中。以该成员为参数调用 k
个索引函数,得到 k
个位数组的索引值,然后根据这些索引值检查位数组:当位数组中所有的对应位均为1时,那么认为该成员已经存在。
如果query的结果为真(即positive),那么实际上存在以下两种可能性:
- 该成员已经被add到集合中,即该成员的确存在。
- 该成员未被add到集合中,但是query过程中检查的所有位均被设置为1(由于添加的其它成员导致)。这种情况被称为false positive。
传统的Bloom filter 不支持从集合中删除成员。对于每个添加到Bloom filter中的成员,实际上将其位数组中的 k
位设置为1。尽管将这些位重置为0可以保证从Bloom filter中删除该成员,但是这样做的副作用是可能会影响某些其它成员,因为其它成员也可能被映射到这些被重置为0的位中的一位或者多位, 从而最终导致false negatives。对于Bloom filter而言,false negatives是不被允许的。 Counting Bloom filter由于采用了计数,因此支持remove操作。
Bloom filter 使用的 k
个index functions,有时也被称为hash functions,它们通常被假定为彼此独立,返回值在可能的取值范围内均匀分布(这是以下一系列数学证明的基础)。
2 The Math
Bloom filter的基本概念并不复杂,接下来分析一下query操作对某个未被添加的成员返回positive(即false positive)的概率:
假设p是位数组中某一位为1的概率, 那么false positive的概率是 pk
。如果n是已经添加到Bloom filter中的成员个数,那么
p = 1 – (1 – 1/m)nk,经过一系列推导得到
p
≈
(
1 – e-kn/m
)
k
,
当 k = m / n * ln2 时(ln 即
loge
),p为最小值。 例如当k
= 8, m/n = 10时, false positive的理论值为0.00846。以下是段计算false positive的实例代码:
public static double calculateFalsePositiveProbability(int k, int m, int n) {
return Math.pow((1 - Math.exp(-k * (double) n / (double) m)), k);
}
对于某些应用而言,false positive的概率已经是一个足够好的判断Bloom filter准确性的指标,Peter C.Dillinger 和 Panagiotis Manolios 在其Bloom Filters in Probablistic Verfification的论文中指出,对于query过程中的不确定性, state omission 是一个更合适的指标。建议感兴趣的读者阅读该论文,顺便也可以复习一下相关的数学知识。
3 Refinement
So far, so good。 跟普通的HashMap相比, Bloom filter不需要在内存中保存key和value, 而是位数组中的若干个位即可,这在内存使用上是个巨大的节省,当然前提是能容忍一定概率的false positives。但是传统的Bloom filter存在以下两个严重的缺陷:
- 为了保证足够低的false positive概率,通常索引函数的个数 k
比较大(例如十几甚至几十,但通常不超过32)。 能找到这么多个random,uniform and independent的索引函数并不是一件容易的事情。
- 数量众多的索引函数,导致add和query的性能不高。
Peter C.Dillinger 和 Panagiotis Manolios在其论文中指出,fingerprinting Bloom filter可以有效地减少索引函数的个数,并且对准确性的影响可以小到忽略。这对于传统的Bloom filter来说,是个重大的改进。笔者使用了其中介绍的triple hashing,认为效果比较明显。
4 Implementation
如果Google以Java实现的Bloom filter, java-bloomfilter 可能是最容易找到的实现之一。它采用的是传统的Bloom filter算法:使用的 k
个索引函数(默认都是MD5),只是索引函数在进行计算时对参数的加盐(salting)不同而已。笔者认为 java-bloomfilter 的性能可能有待提升。
Hadoop common的util包中也提供了一个Bloom Filter的实现,此外其hash包还提供了JenkinsHash 和 MurmurHash 两个Hash算法。笔者感觉Hadoop 的Bloom filter的实现方式类似fingerprinting Bloom filter,但是没有使用double hashing 或者tripple hashing。
此外关于位数组的实现方式,可能最直接想法的是使用java.util.BitSet。不过笔者认为如果处理的数据量很大、或者性能要求比较高,那么不建议使用java.util.BitSet, 因为java.util.BitSet的内存使用方式、总体性能都不是很理想。
5 Reference
- Bloom Filters in Probablistic Verfification. Peter C.Dillinger and Panagiotis Manolios
- Hadoop的Bloom filter实现。http://hadoop.apache.org/common/
- java-bloomfilter. http://code.google.com/p/java-bloomfilter/
分享到:
相关推荐
Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不...
bloom filter(布隆过滤器)应用很广泛的高效算法,研究研究
bloomfilter.js, 使用FNV的JavaScript bloom filter快速散列 Bloom过滤器This过滤器实现使用非加密 Fowler-Noll-Vo散列函数来实现速度。用法var bloom = new BloomFilter( 32 * 256,//number of bits to all
Bloom filter是一个简明的空间效率极高的随机的数据结构。用Bloom filter 表示 cache 内容 ,可以高效地实现cache 协作。本文对BloomFilter及其改进型进行了综述性分析,探讨了它的实用性。
分布式环境下改进的BloomFilter过滤技术
This is the bloom filter of 2.5 Million ... BloomFilter bf=new BloomFilter(); BitSet bitSet=bf.readBit(fileName); bf.setBits(bitSet); System.out.println(bf.exist("password")); } it will says true.
leveldb中bloomfilter的优化。
Respect! The original paper about bloom filter. Very beginning of hash error tolerate algorithm to get wanted data faster.
相似项发现主题中的shingling、simhash、bloom filter算法java实现,测试通过,附带测试数据。
bloom filter的一些论文 有综述,有应用,较为详细 不过可能需要下载cnki的阅读器,这个比较好下,大家可以自己下个
提出一种针对动态集合的矩阵型Bloom filter表示与查找法(matrix Bloom filter,MBF),它使用一个s×m位矩阵对数据集合进行哈希表示与查找,较同类算法SBF和DBF,能继承Bloom filter算法常数查找开销的基本精髓。
这是一个java版的bloomFilter Hash函数集,并带有测试程序。在我的资源里还有一个c版的,函数功能相同,在我的应用中具有良好表现。
介绍Bloom Filter(布隆过滤器)原理、实现及具体应用,包含9个不同PPT及PDF文档资料,对Bloom Filter感兴趣、想学习的同学可以下载查看下
鉴于失败的DNS查询(failed DNS query)能提供恶意网络活动的证据,以DNS查询失败的数据为切入口,提出一种轻量级的基于Counting Bloom Filter的DNS异常检测方法。该方法使用带语义特征的可逆哈希函数对被查询的域名...
linux下编写的网络爬虫,可以实现bloom filter 去重过滤,不过是用来垂直爬取www.8684.cn网站的。运行的时候请输入www.8684.cn
该文档中包含 bloomFilter过滤器中用到的对于字符串进行hash的hash函数共十一个,并带有测试程序..
改良的bloomfilter,数据支持多字段,可只查询部分字段。创建时,可指定不存储的字段组合(用于节省空间)
Java-BloomFilter, 在Java中,一个独立的Bloom过滤器 java-bloomfilterJava bloomfilter是一个独立于Java的Bloom过滤器实现。 它旨在在不需要额外库开销的情况下包含在现有项目中。 第一个版本是由 Ian的博客条目...
bloom filter布隆过滤器学习资料大全,收集了很多相关的论文,并总结了各种布隆过滤器的变种