布隆过滤器的原理及使用
布隆过滤器的原理及使用
一、BloomFilter简介
BloomFilter是大数据领域中经常使用到的算法,主要用于在海量的数据中判断一个数据是否已经存在,但
如果不存在,判断结果一定是正确的。如果存在判断结果可能出现错误;这种数据结构的速度是非常快的,内
存消耗得比较小,使用很方便,在各种编程语言中都有对应实现的类库
二、Bloom的原理
BloomFilter本身是一个非常长的二进制向量(可以看成一个位数组)和一个映射函数。这个位数组初始情
况下内部全部是0,长度是m;对于每个新增的项,我们使用K种不同的hash算法对他计算hash值,可以得到K
个hash值,再使用这些hash值对m取模映射到数组范围内,假设取模后的结果是x,便会把x值对应的位置标记
为1,过程图如下:
但是当插入的数据大幅提升的时候,位数组中大部分的元素就会被置成1。此时如果查询一个元素,通过
哈希函数映射到的位置可能已经被标记了,这时候就会出现误判;但是如果所有映射的位置中出现未被标记的
位置,那么这个元素一定是不存在的,原理示意图如下:
我们可以使用Python将Bloomfilter实现的原理用代码实现:
#插入元素
def BloomFilter(filter,value,hash_functions):
m = len(filter)
for func in hash_functions:
idx = func(value) % m #哈希映射取模
filter[idx] = True #对应的位置进行标记
return filter
#判断元素
def MemberInFilter(filter,value,hash_functions):
m = len(filter)
for func in hash_functions:
idx = func(value) % m
if not filter[idx]:
return False
return True
通过上面的代码实现我们可以看到BloomFilter插入数据和查询数据时的时间复杂度都是O(k),其中k是哈
希函数的个数;注意一点BloomFilter是不支持删除的,因为它的每一位并不是独占的,很有可能多个元素共享了
某一位,如果我们直接删除这一位的话,可能会影响其他元素
三、BloomFilter的使用
BloomFilter的设计实际上是非常复杂的,但是好在各种编程语言都有对应的实现;比如Java中的Guava中就
有BloomFilter的具体实现;Python中的pybloom包中也有两个类用来实现BloomFilter的功能,简单介绍下Python
中这种数据结构的使用吧
pip install bloom-filter #安装bloom-filter对应的包
#基本的使用如下
from bloom_filter import BloomFilter
bloom = BloomFilter(max_elements = 10000,error_rate = 0.1)
#max_elements是其存储的最大元素数量,error_rate是误判率
# BloomFilter为空时,测试test_key是否存在
assert "test-key" in bloom is False #不存在
# 添加元素
bloom.add("test-key")
# 再次查询是否存在
assert "test-key" in bloom is True #存在
四、BloomFilter的典型应用
网页爬虫中,避免爬取相同的URL地址
反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否是垃圾邮箱
缓存击穿,将已经存在的缓存置于布隆过滤器中,如果访问不存在的缓存可以迅速判断