布鲁姆过滤器
BloomFilter介绍
布鲁姆过滤器的结构
布鲁姆过滤器是啥
布鲁姆过滤器是一种特殊的哈希表,这个哈希表中的每一个槽只存储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,就是不再数据集合中的元素误判在集合中。如下就是这种情况。
这样的情况在所难免,但造成伤害并不大,只是多了一次不必要的搜索。为了避免这情况的出现,就应该合理地设计过滤器的大小和哈希函数的个数:空间过小,哈希函数过多,会造成数据的拥挤增加误判的几率。
根据笔者参阅过的论文,假设有 k
个哈希函数, n
个要存储的数据,布鲁姆过滤器的长度为 m
,那么要使得误判率最小则。
删除元素
到了这里,又开始产生新的问题了,由于数据的存储往往是变动的,有添加必然会有删除。那么问题来了:根据上述的布鲁姆过滤器的结构,删除元素是不能做到的。就用上图的例子,A和B在存储到布鲁姆过滤器中时,有部分映射到的位置是一样的,所以如果删除A或者是删除B都会对另一方之后的判断造成影响。
所以为了改进这一点,布鲁姆过滤器还可以进一步改进:每一个槽的空间由,存储的值由
。
这样以后每一次添加新的元素的时候,就在映射到的槽的内容;查找的时候就判断映射到的每一个槽的数值
则存在;删除的时候,就将对应的槽的内容
,但这种删除很多时候“逻辑上”还是没有删彻底,造成之后查找误判的几率上升。
总结
- 布鲁姆过滤器就是压缩的特殊哈希表。
- 是一个集合。
- 在内存中运行。
- 一般用于判断元素是否存在于集合中。