Bloom Filters布鲁姆过滤器

Bloom Filters by Example (链接:http://billmill.org/bloomfilter-tutorial/

以下是关于布鲁姆过滤器的知识点

布隆过滤器是一种数据结构,快速和节省内存,能用于判定一个元素是否存在于一个集合中。
这种效率的代价是Bloom filter是一种概率数据结构,元素不是绝对的在组里或可能在组里。
Bloom filter的基本数据结构是一个位向量。

在以下文本,我们 ķ个 哈希值,m位的过滤器 ,和n 已插入的元素来介绍Bloom filter

哈希函数

Bloom filter应使用的哈希函数是独立和均匀分布的,使哈希函数运行时尽可能的快。(而加密散列如sha1,尽管被广泛使用,但不是很好的选择)。

例子:简单的散列足够独立,其中包括 murmur, the fnv series of hashes, and Jenkins Hashes.


然而2016年8月31日的更新:Murmur(杂音)似乎被打破了。现在你可能更喜欢SipHash。
在一个快于加密哈希函数中可以看到区别当开启一个 bloom filter 从md5到Murmur的实现时,增速提高到了~ 800%。

关于bloom filter的实现有个简短的调查
Cassandra uses Murmur hashes Hadoop includes default implementations of Jenkins and Murmur hashes python-bloomfilter uses cryptographic hashes Plan9 uses a simple hash as proposed in Mitzenmacher 2005 Sdroege Bloom filter uses fnv1a (included just because I wanted to show one that uses fnv.) Squid uses MD5

双散列
注意,您不需要选择两个或两个以上不同的哈希函数。相反,您可以通过两双散列函数创建任意数量的新散列函数。
给定两个独立的哈希函数a,b和一个value值 x,你可以创建一个新的哈希散列函数:
hashi(x, m) = (hasha(x) + i × hashb(x)) mod m

How big should Imake my Bloom filter?

能通过误报修改你 Bloom filter的过滤速度,这 是一个很好的特性。更大的过滤器将具有更少的误报,而较小的则误报会多一点。
误报率将约为(1-e-kn/m)k,所以你只需按你的期望插入n元素的数量,并尝试不同的k值和m值,为您的应用程序配置过滤器。

但这导致一个明显的问题: How many hash functions should I use?

哈希函数越多,导致过滤器越慢,并且的更快。如果过少,可能会有很多误报。
当你必须选择ķ来创建过滤器,你必须确定n值大概在什么范围,一旦你确定了,你还要确定一个潜在的k(哈希函数的数量)和一个m(比特)。
这似乎是一个困难的优化问题,但幸运的是,给定一个m和n,有一个函数能选择最优值k:(m/n)ln(2)
因此,要选择bloom filter的大小:
  1. 选择一个大概值n
  2. 选择一个值m
  3. 计算的最优值ķ
  4. 计算我们所选择的值的错误率nm,和ķ。如果这是不可接受的,回到步骤2和改变m; 否则我们就完成了

How fast and space efficient is a Bloom filter?

如何快速,节省空间

给定一个m比特和k个散列函数的bloom filter,复杂度是O(K)。
也就是说,每次想添加一个元素到集合,你只需要在ķ个散列函数中运行元素将其添加到集合或检查所在的位。

空间优势很难总结,这取决于你愿意容忍的错误率。这也取决于元素插入的潜在范围;如果是非常有限的,使用一个确定的位向量会更好。如果你甚至不能大概的估计要插入的元素数量,你最好有一个哈希表或做一个可伸缩的bloom filter。

参考

1:布鲁姆过滤器的网络应用程序:调查,布罗德和Mitzenmacher。一个很好的概述。

2:维基百科,这对布鲁姆过滤器的出色和全面的网页

3:少散列,同样的性能,基尔希和Mitzenmacher

4:可扩展布鲁姆过滤器,阿尔梅达等人

5: 如何用c++撰写布鲁姆过滤器, Michael Schmatz


(如若有翻译或者知识错误,欢迎留言评论)

你可能感兴趣的:(Bloom,Filters)