布隆过滤器

使用场景

布隆过滤器是一种数据结构,旨在快速、高效地判断一个元素是否存在于一个集合中

优缺点

优点当然是时间复杂度很低.但他也有缺点,布隆过滤器是一个概率数据结构
它告诉我们,该元素要么肯定不在集合中(not_in),要么可能(maybe_in)在集合中。(会告诉你maybe_in的概率.)

原理&实践

布隆过滤器的基本数据结构是一个比特数组。下面是一个demo数组,我们将用来演示。

image.png

该表中的每个空单元代表一个bit,下面的数字则是其索引Index。要向布隆过滤器添加一个元素,我们只需对其进行几次hash,并将这些hash结果所在的索引处的比特置为1。

例如,我们把集合["yanxin","yanxiaori","yanbo"], 通过Fnv和Murmur计算后, 把结果添加到布隆数组中
(Fnv和Murmur是两个简单的哈希函数。)

image.png

当你添加一个字符串时,你可以
image

看到哈希值给出的索引处的比特被设置为1。我用绿色来显示新添加的,但任何彩色单元都只是1。

image.png

为了测试成员资格,你只需用相同的哈希函数对字符串进行哈希,然后看这些值是否在比特向量中被设置。如果不是,你就知道这个元素不在这个集合中。如果它们是,你只知道它可能是,因为另一个元素或其他元素的一些组合可能设置了相同的位。再一次,我们来演示一下。

image.png

以上就是布隆过滤器的基本概念.

高级

在我写更多关于布鲁姆过滤器的内容之前,先声明一下:我从来没有在生产中使用过它们。请不要相信我的话。我所要做的只是给你一个大致的概念,并指出你可以在哪里找到更多。

在下面的文字中,我们将提到一个有k个哈希值的布隆过滤器,过滤器中的m个比特,以及被插入的n个元素。

哈希函数

布隆过滤器中使用的哈希函数应该是独立的、均匀分布的。它们还应该是尽可能快的(像sha1这样的加密散列函数,虽然被广泛使用,但并不是很好的选择)。

足够独立的快速、简单的哈希值的例子包括murmur、fnv系列的哈希值和HashMix。

要看到比加密哈希函数更快的区别,请看这个故事,当把一个bloom filter的实现从md5切换到murmur时,速度提高了大约800%。

在一个简短的布隆过滤器实现的调查中。

Chromium使用HashMix。(另外,这里有一个关于他们如何使用bloom filter的简短描述)
python-bloomfilter使用加密的哈希值
Plan9使用Mitzenmacher 2005中提出的简单哈希值
Sdroege Bloom filter使用fnv1a(包括在内只是因为我想展示一个使用fnv的。)
Squid使用MD5

布隆过滤器的时间和空间复杂度如何?

给定一个有m个比特和k个散列函数的布隆过滤器,插入和成员测试都是O(k)。
也就是说,每次你想向集合添加一个元素或检查集合成员资格时,你只需要通过k个散列函数运行该元素,并将其添加到集合中或检查这些比特。

空间方面的优势更难总结;这同样取决于你愿意容忍的错误率。这也取决于要插入的元素的潜在范围:
如果它非常有限,一个确定性的比特向量可以做得更好。如果你甚至不能粗略估计要插入的元素的数量,你可能最好使用哈希表或可扩展的布鲁姆过滤器4。

参考

https://llimllib.github.io/bloomfilter-tutorial/

你可能感兴趣的:(布隆过滤器)