简洁理解
直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中。和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一个标志,用来判断key是否在集合中。
算法过程
数组的每个元素都只占1bit空间,并且每个元素只能为0或1。
布隆过滤器还拥有k个哈希函数,当一个元素加入布隆过滤器时,会使用k个哈希函数对其进行k次计算,得到k个哈希值,并且根据得到的哈希值,在维数组中把对应下标的值置位1。
判断某个数是否在布隆过滤器中,就对该元素进行k次哈希计算,得到的值在位数组中判断每个元素是否都为1,如果每个元素都为1,就说明这个值在布隆过滤器中。
优缺点
优点
不需要存储key,节省空间
缺点
-
- 算法判断key在集合中时,有一定的概率key其实不在集合中
-
- 无法删除
python实现布隆过滤器
from bitarray import bitarray
import mmh3
class BloomFilter:
"""
Bloom Filter implemented in Python
"""
def __init__(self, n, p):
"""
:param n: Size of bit array
:param p: False positive probability
"""
self.n = n
self.p = p
self.bit_array = bitarray(self.n)
self.bit_array.setall(0)
# Number of hash functions
self.k = self.get_k(n, p)
def add(self, item):
"""
Adds an item to the bloom filter
"""
for i in range(self.k):
hash_value = mmh3.hash(item, i) % self.n
self.bit_array[hash_value] = True
def check(self, item):
"""
Checks if an item is present in the bloom filter
"""
for i in range(self.k):
hash_value = mmh3.hash(item, i) % self.n
if self.bit_array[hash_value] == False:
return False
return True
def get_k(self, n, p):
"""
Returns the number of hash functions needed
to achieve the required false positive probability
"""
k = (n * math.log(2)) / math.log(1/p)
return int(k)
bloom = BloomFilter(100000, 0.01) # 1% error rate
bloom.add("hello")
bloom.add("world")
bloom.check("hello") # Returns True
bloom.check("no") # Returns False
应用案例
- 爬虫使用redis去重
- 缓存系统:使用布隆过滤器判断查询是否在缓存当中
- 垃圾邮件过滤:通过布隆过滤器判断邮件是否在垃圾邮件列表当中,从而过滤垃圾邮件
- 黑名单过滤: 判断ip/手机号是否存在黑名单当中,从而组织恶意请求