题目:
不安全网页黑名单包含100亿个黑名单网页,每个网页的URL最多占用64B。现在要实现一种网页过滤系统,可以根据网页的URL判断该网页是否在黑名单上。
要求:
该系统允许有0.01%的误判率。
使用的额外空间不超过30GB。
思路:
首先对所有的URL通过哈希保存进而查询显然是不可能的,不满足第二个要求。(空间需求达到了640GB)
对于 网页黑名单系统 & 垃圾邮件过滤系统 & 爬虫网址判重系统等,而且系统一般允许一定的失误率,对空间要求比较严格。
这类问题一般都可以由布隆过滤器解决。
布隆过滤器:精确代表一个集合 并可以精确判断一个元素是否在集合之中。
但是不可能完全精确,其优势在于利用较少的空间达到相对较高的准确率。
假设有一个长度为m的bit类型数组,如图。
假设有k个hash函数,其输出都>=m,这些hash函数之间都彼此独立。
对于同一输入对象,经过k个hash函数的结果也是相互独立的。将计算结果对m取余,将上图中相应位置设置为1。
按照上述这种操作,bit数组某些位置会被涂黑。对于所有的输入都执行这种操作,最终bit数组大部分位置可能被涂黑,这样就生成了一个布隆过滤器。
接下来,对于某个给定的输入对象,检测其是否是已输入的对象,可将该对象通过k个hash函数算出k个值并对m取余。检查这些位置是否在bit数组中被涂黑。
如果有一个不为黑,说明这个输入对象肯定不在集合中。
如果都为黑,那么这个输入对象可能在集合中,也可能出现误判。【误判具体产生是由于输入对象过多但是bit数组太小 导致数组的大部分位置都已经涂黑。】
下面给出布隆过滤器的大小m的公式:
其中 n为输入对象的个数,p为系统要求的误判率上限。【最后m需要向上取整】
hash函数的个数由下面式子确定:
注:更详细的计算推导请参考这个链接:
http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html
最后说明的是,布隆过滤器会出现误判的情况,可以通过对已知的误判样本建立白名单的方式防止误判。
参考:
1. 本文的内容参考自左神新书,在此表示感谢。
2. http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html