1.什么是布隆过滤器?
本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
2布隆过滤器数据结构
我们可以把它看作由二进制向量(或者说位数组)和一系列随机映射函数(哈希函数)两部分组成的数据结构,相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。
位数组中的每个元素都只占用 1 bit ,并且每个元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000 / 8 = 125000 B = 125000 byte ≈ 125kb 的空间。
总结:一个名叫 Bloom 的人提出了一种来检索元素是否在给定大集合中的数据结构,这种数据结构是高效且性能很好的,但缺点是具有一定的错误识别率和删除难度。并且,理论情况下,添加到集合中的元素越多,误报的可能性就越大。
3布隆过滤器的原理介绍
3.1 数据添加
1.使用布隆过滤器中的哈希函数对元素值进行计算,得到哈希值(有几个哈希函数得到几个哈希值)。
2.根据得到的哈希值,在位数组中把对应下标的值置为 1。
3.2校验数据是否存在
1.对给定元素再次进行相同的哈希计算;
2.得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。
布隆过滤器hash计算
如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后在对应的位数组的下表的元素设置为 1(当位数组初始化时 ,所有位置均为0)。当第二次存储相同字符串时,因为先前的对应位置已设置为1,所以很容易知道此值已经存在(去重非常方便)。
如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。
备注:不同的字符串可能哈希出来的位置相同,这种情况我们可以适当增加位数组大小或者调整我们的哈希函数。
4.布隆过滤器使用场景
重点:布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在
1.判断给定数据是否存在:海量数据(数据亿级)存储校验、防止缓存穿透、邮箱的垃圾邮件过滤、黑名单功能等;
2.去重功能
5.计算公式(结合实际场景应用推导更加直观)
场景:不安全网页的黑名单包含100亿个黑名单网页,每个网页的URL最多占用64字节。现在想要实现一种网页过滤系统,可以根据网页的URL判断该网站是否在黑名单上,请设计该系统。要求该系统允许有万分之一以下的判断失误率,并且使用的额外空间不要超过30G。
思路:布隆过滤器的bitarray大小如何确定?
变量说明:
- m:容量大小
- n:样本元素数量
- p:失误率
- k:hash函数个数
1.设bit array大小为m,样本数量为n,失误率为p。
2.由题可知 n = 100亿,p = 0.01%
3.单个样本大小不影响布隆过滤器大小,因为样本会通过哈希函数得到输出值。
4.使用样本数量n和失误率p可以算出m,公式为:
求得 m = 19.19n,向上取整为 20n。所以2000亿bit,约为25G。
所使用哈希函数个数k可以由以下公式求得:
所以 k = 14,即需要14个哈希函数。
通过 m = 20n, k = 14,可以通过以下公式算出设计的布隆过滤器的真实失误率为0.006%。