布隆算法(微信公众号)

来源:互联网 发布:开农村淘宝靠什么赚钱 编辑:程序博客网 时间:2024/05/29 08:54

今天我们来聊聊布隆算法。


爬虫的原理就不细说了,无非是通过种子 URL 来顺藤摸瓜,爬取出网站关联的所有的子网页,存入自己的网页库当中。


爬取出来的 URL 有可能存在重复,需要被丢弃掉,如何实现 URL 的去重呢?


URL去重方案第一版:HashSet

创建一个HashSet集合,把每一个URL字符串作为HashSet的key插入到集合当中,利用HashSet的Key唯一性来对URL做去重。

这个方案看似没毛病,但是经过几轮压测之后......‘’

每一个URL按照20字节来算,一亿个URL就是20亿字节,也就是大约占了1.8G以上的空间。这么大的HashSet集合显然是不可取的。


URL去重方案第二版:Bitmap


Bitmap是一种节省空间的数据结构,不太了解的朋友可以看看往期的相关文章:

具体怎么做呢?获取每一个URL的HashCode,根据HashCode的值来插入到Bitmap的对应位置。如果要插入位置的值已经是1,说明该URL已重复。

使用Bitmap以后,每一个Url只占了1个Bit,一亿个Url占约12MB。假设整个Bitmap的空隙比较多,额外空间占90%,总空间也不过是120MB,相比HashSet来说大大节省了内存空间。

String的Hashcode方法虽然尽可能做到均匀分布,但仍然免不了会有冲突的情况。HashCode的冲突意味着什么呢?意味着两个原本并不相同的Url被误判为重复Url。


布隆算法是一种以 Bitmap 集合为基础的排重算法。

布隆算法有许多的应用场景,比如 Url 的排重,垃圾邮箱地址的过滤等领域。


实现多个不同的 Hash 算法,让每一个 Url 都计算出多个 Hash 值,最后让各个 Hash 值一一比较。


1.把第一个URL按照三种Hash算法,分别生成三个不同的Hash值。

2.把第二个URL也按照三种Hash算法,分别生成三个不同的Hash值。

3.依次比较每一个Hash结果,只有当全部结果都相等时,才判定两个URL相同。

假设标准 HashCode 的重复概率是 0.01%, 那么 3 个 Hash 结果同时重复的概率就是 0.01%^3 = 0.0000000001%


向上面这样,就是布隆算法对于海量数据的过滤流程。


【误判】

为了减小误判的概率,可以让 Bitmap 的空间更大一些,单个 Url 所做的 Hash 更多一些(一般是 8 次),总之是在空间和准确率上做出取舍。


还有一个问题,既然使用同一个 Bitmap 会出现误判,为什么不让每一种 Hash 算法的结果对应一个独立的 Bitmap。

那样的话,占用的空间也会相应增加几倍,反而不如用 HashSet。


如果想完全杜绝误判的情况,应该怎么办?

对于爬虫来说,可以容许极少量的 Url 误判为重复。如果是用于垃圾邮箱的过滤,可以考虑加上一个白名单,专门存储那些被误判的正常邮箱。


问题实例

1、给你A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL。如果是三个乃至n个文件呢?

分析:如果允许有一定的错误率,可以使用Bloom filter,4G内存大概可以表示340亿bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit,然后挨个读取另外一个文件的url,检查是否与Bloom filter,如果是,那么该url应该是共同的url(注意会有一定的错误率)。