布鲁姆过滤器

BloomFilter介绍

布鲁姆过滤器的结构

一个存储01串的连续空间,多个哈希函数
image.png

布鲁姆过滤器是啥

布鲁姆过滤器是一种特殊的哈希表,这个哈希表中的每一个槽只存储0或1,所以可以使用计算机中的最小单位 bit 来存储每一个01以达到空间的极大节省。在数据集非常大的条件下进行某个数据对象A的查找即使是利用哈希表仍然会有很大的开销,尤其是当要在多个独立分布的数据集中查找的时候开销更加明显。


这个时候布鲁姆过滤器就派上用场了,由于每个数据位非0即1,所以布鲁姆不是用来存储对象数据的,而是用来判断对象是否在某个大量的数据集中。它的使用如下:

  • 每一个数据集 storage 备有一个一定长度的布鲁姆过滤器 bf ,有多个哈希函数(这里举例有三个) h1 h2 h3 ;那么当我们加入数据到 storage 中时,同时利用 h1 h2 h3 三个哈希函数分别为此数据映射三个在 bf 中的下标 i1 i2 i3 ,在 bf 中对应的槽置一 bf[i1] = bf[i2] = bf[i3] = 1 ,就标识了此数据存放在了这个 storage 中。
  • 当我们在多个独立数据集中查找某个数据时,就先不直接到数据集中查找,而是先去看看数据集的 bf ,将此数据通过三个哈希函数映射出三个下标,若 bf 的这三个位置都为1,此数据集才有之后查找的意义;否则只要有一个位置为0,说明要查找的数据必然不在这个数据集中,跳到下一个数据集重复此步。


所以一般为了快速的判断,布鲁姆过滤器是存放在内存中的,而真实的数据是存储在硬盘中。

假阳性

布鲁姆过滤器的假阳性就是指原本不在数据集中的数据,通过多个哈希函数的映射到过滤器上却每一个位置都是1,就是不再数据集合中的元素误判在集合中。如下就是这种情况。
image.png
image.png
这样的情况在所难免,但造成伤害并不大,只是多了一次不必要的搜索。为了避免这情况的出现,就应该合理地设计过滤器的大小和哈希函数的个数:空间过小,哈希函数过多,会造成数据的拥挤增加误判的几率。


根据笔者参阅过的论文,假设有 k 个哈希函数, n 个要存储的数据,布鲁姆过滤器的长度为 m ,那么要使得误判率最小则

删除元素

到了这里,又开始产生新的问题了,由于数据的存储往往是变动的,有添加必然会有删除。那么问题来了:根据上述的布鲁姆过滤器的结构,删除元素是不能做到的。就用上图的例子,A和B在存储到布鲁姆过滤器中时,有部分映射到的位置是一样的,所以如果删除A或者是删除B都会对另一方之后的判断造成影响。


所以为了改进这一点,布鲁姆过滤器还可以进一步改进:每一个槽的空间由,存储的值由

这样以后每一次添加新的元素的时候,就在映射到的槽的内容;查找的时候就判断映射到的每一个槽的数值则存在;删除的时候,就将对应的槽的内容,但这种删除很多时候“逻辑上”还是没有删彻底,造成之后查找误判的几率上升。

总结

  • 布鲁姆过滤器就是压缩的特殊哈希表。
  • 是一个集合。
  • 在内存中运行。
  • 一般用于判断元素是否存在于集合中。
posted @ 2020-03-26 15:24  Bankarian  阅读(1020)  评论(0编辑  收藏  举报