布隆过滤波器
本质上来讲,布隆过滤器是一种数据结构,是一种低成本、高性能、巧妙的概率型数据结构(probabilistic data structure),可以高效地更新和查询,可以用来实现大数据量情况下的 “某样东西一定不存在或者可能存在” 。
这种看似不能够100%的告诉我们准确结果的数据结构,由于其低成本的实现,其实已经大大满足了我们的实际生产环境的需求,能够帮助我们快速在大数据量的情况下做出可靠的反应。
布隆过滤器的核心技术实现就是bit array,由于bit只能代表0和1,因此这就是布隆过滤器高性能和低成本的关键。
实际场景
假设我们有一个不安全网页的黑名单,数量为100亿个,每个网页的URL最多占用64B。我们现在需要实现一个黑名单过滤系统,用来判断请求访问的地址是不是属于黑名单之内。
要求
- 该系统允许有0.01%的失误率。
- 使用的额外空间不超过30GB。
思考
如果我们使用数据库或者hash table来直接存储100亿个黑名单网页,就需要640GB的存储容量,这显然不符合要求。
解决思路
为了解决这个问题,我们需要使用布隆过滤器的知识。
hash函数,亦称散列函数
- 典型的哈希函数都有无限的输入值域;
- 当给哈希函数输入的内容一致时,则返回值一样;
- 当给哈希函数输入的值不一样时,返回值有可能一样,也可能不一样, 但是返回值域都会分布在S上;
- 海量不同的输入值经过哈希函数的计算,得到的返回值都会均匀的分布在S上;
使用好布隆过滤器的关键是哈希函数的个数、bit array的大小。
布隆过滤器的大小由以下公式确定:
m=-\frac{n*ln p}{(ln2)^2}
根据公式计算得出,m=19.19n,我们向上取整为20n,即需要2000亿个bit,也就是25GB。
哈希函数的个数由以下公式计算得出:
k=ln2*\frac{m}{n}=0.7*\frac{m}{n}
哈希函数的个数为:k=14
因为我们在计算布隆过滤器大小时,选择了向上取整,因此还需要用如下公式确定布隆过滤器的真实失误率:
(1-e^\frac{nk}{m})^k=0.006%
真实失误率为0.006%,这是比0.01%更低的失误率,因此呢,该方法是符合实际要求的。
布隆过滤器失误率分析:假设布隆过滤器中的k个哈希函数足够好且各自独立,每个输入对象都等概率的散列到bitmap中m个bit中任意k个位置,且与其他元素被散列到哪里无关。那么对于一个bit来说,一个输入对象在被k个哈希函数散列后,这个位置依然没有被涂黑的概率为:
(1-\frac{1}{m})^k
经过n个输入对象后,这个位置依然没有被涂黑的概率为:
((1-\frac{1}{m})^{kn}
那么被涂黑的概率就为:
1-(1-\frac{1}{m})^{kn}
那么在检查阶段,检查k个位置都为黑的概率为:
(1-(1-\frac{1}{m})^{kn})^k=(1-(1-\frac{1}{m})^{-mx^{\frac{-kn}{m}}})^k
在x->0时,(1+x)^(1/x)->e,上面等式的右边可以认为m很大的数,所以-1/m->0,所以简化为:
(1-(1-\frac{1}{m})^{-mx^{\frac{-kn}{m}}})^k\sim(1-e^{-\frac{nk}{m}})
布隆过滤器会有误报,但是我们可以对误报样本建立白名单来防止误报。
布隆过滤器对于大数据相关的题目能够很好的解决。
\