Bloom Filter

蜘蛛在网络间爬行很可能会形成“环”。为了避免形成“环”,就需要知道蜘蛛已经访问过那些URL。有如下几种方案:

  1. 将访问过的URL保存到数据库。

  2. 用HashSet将访问过的URL保存起来。那只需接近O(1)的代价就可以查到一个URL是否被访问过了。

  3. URL经过MD5或SHA-1等单向哈希后再保存到HashSet或数据库。

  4. 建立一个BitSet,将每个URL经过一个哈希函数映射到某一位。

  

方法1~3都是将访问过的URL完整保存,方法4则只标记URL的一个映射位。 以上方法在数据量较小的情况下都能完美解决问题,但是当数据量变得非常庞大时问题就来了。

  1:数据量变得非常庞大后关系型数据库查询的效率会变得很低。而且每来一个URL就启动一次数据库查询是不是太小题大做了?

  2:太消耗内存。随着URL的增多,占用的内存会越来越多。若有1亿个URL,每个URL只算50个字符,就需要5GB内存。

  3:由于字符串经过MD5处理后的信息摘要长度只有128Bit,SHA-1处理后也只有160Bit。

  4:消耗内存是相对较少的,但缺点是单一哈希函数发生冲突的概率太高。若要降低冲突发生的概率到1%,就要将BitSet的长度设置为URL个数的100倍。

1.散列冲突

2.布隆过滤器

采用包含m位的位数组存储,将n个元素集合S={x1, x2,…,xn} ,用k个相互独立的哈希函数映射到{1,…,m}的范围中。

2.1插入

S{x,y,z}集合中的每个元素,用3个hash函数映射到{1,…,18}范围内,将相应的位置为1

2.2查找 

w表示待查询元素,用相同的3个hash函数,将w映射到{1,…,18}范围内,如果每位都是1,则表示w在集合中,否表表示不在集合中

参考:

http://blog.csdn.net/jiaomeng/article/details/1495500

http://www.importnew.com/13032.html#comment-560449

http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html

原文地址:https://www.cnblogs.com/yuyutianxia/p/7039697.html