[TOC]
布隆过滤器的思想 — 不追求完美
在quora上,有个问题问,人们最常犯的错误是哪些,其中一个就是追求完美。
在it领域,为了让系统完美化,比如之前涉及存储系统,去重时想达到完美的标准,花的代价是2小时,如果稍加改动,可以让代价降低到1分钟左右,只有本来的百分之一不到。
布隆过滤器的思想,也是如此。
布隆过滤器的应用 – 使用案例
squid
squid里的cache digests 用的是布隆过滤器
chrom
chrom里判断恶意链接,也是用的布隆过滤器
hbase里也用了bloom filter
如图
bloom filter在hbase里的用法比较有意思,它先判断大小,再做bf,这样能让查询速度加快几十倍
布隆过滤器的缺点和改进
缺点
布隆过滤器的缺点是错判,就是说,不在里面的,可能判断成在里面,但是在里面的,一定不会错,而且,无法删除
改进
改进1 多bit
bloom filter其实就是bitmaq的改进,bitmap是单个hash,而bf是多个hash,本质上,都是一个bit只能存有或者没有两种状态
可以考虑用多bit记录的方式,这种方法,就是本来每个bit不是0就是1,现在可以记录其它的,如果add一个元素,把对应bit的数字加1即可
如果要del一个元素,对应位置的数字减1即可
好处是,可以删除元素
缺点是,可能会有位溢出,另外,错判还是会发生,速度也慢了
改进2 白名单
还有种改进方式是对一些常见的url加到白名单里
这种改进是不错的选择,对于某些不考虑过滤的url,可以先判断一下,剩下的url错判就错判,对结果影响是可以接受
布隆过滤器的细节 – 算法的实现
下面用pybloom演示一下布隆过滤器的用法
from pybloom import BloomFilter
from pybloom import benchmarks
f = BloomFilter(capacity=100000, error_rate=0.1)
# [f.add(x) for x in range(102)]
[f.add(x) for x in range(1001)]
for x in range(1001, 100000000):
if x in f:
print x
可以看出,布隆过滤器,还是比较高效的一种数据结构
布隆过滤器的实践 – 爬虫应用
布隆过滤器比较麻烦的一点是无法删除,爬虫是增量型的,不可能永远爬下去,浪费资源,也没那么多空间
如果,每周一起一个bllomfilter,听起来不错,但是你周一的时候,周一爬虫看的那些url之前的就没法儿过滤了
有个折中的办法是爬虫运行时候,用一个布隆过滤器bf1,爬虫读取页面的时候,把时间也过一下,只爬取当天以及三天以内的数据,然后在每周四起一个新的布隆过滤器bf2
写的时候,写两份,一份到bf2,一份到bf1
每周一开始,bf1就停掉,换用bf2作为查重的bloomfilter,周而复始,就可以了