您的位置:首页 > 理论基础 > 计算机网络

网络爬虫项目开发日志(七): 基于MD5去重树的爬虫设计与优化

2016-11-22 09:20 791 查看
--注--

本文仅做研究交流用,非工业化标准,各位大神不喜勿喷哈

--引言--

爬虫系统在面对海量网页数据时,会因为DNS解析以及URL去重而消耗大量的时间,为了更好的改进爬虫的效率,让爬虫在大数据处理时依然拥有良好的性能,我打算使用哈希链表缓存DNS,效率提升2.5~3倍,再将MD5双发以及树结合设计出一种基于MD5的url去重树,理论上使得url去重的空间复杂度相对于普通哈希表缩小60倍,而且让其查重的时间复杂度接近于O(1)。

关于DNS解析,实际项目中,我们是用redis来缓存的,在此不做赘述,我们主要来说下URL去重的问题:

--开始--

互联网上的链接多达几十亿甚至上百亿,而其中有许多url的长度为上百个字符,更有甚者可以达上千个字符。假如爬虫已经抓取了50亿的网页,而每个url平均所占字符为64b,那么存储这些url所需内存接近300G!这个数据非常可怕,不仅因为我们的机器需要一个300G的内存,更意味着爬虫每找到一个新的url都需要遍历这300G的内存,资源损耗太大。

为了提高爬虫效率,需要一个更好的数据结构来保存这些已访问的url。三个方面的要求:

1)查找速度,快速查找

2)去重效果,降低碰撞概率

3)空间复杂度,尽量洁身空间

本文利用MD5加密的抵碰撞率,再根据MD5的特性与数结合形成了一种新的存储方法,结构图如下:



去重树的深度为MD5的位数即16层或者32层,去重树的节点值是0-9、a-f中的一个,所以每个节点都有16个指针指向下一个节点。去重树的基本思想及实现步骤如下:

1)强url进行16位MD5压缩。MD5加密算法有16位和32位两种,16位的碰撞率为2的64次方之1.其实就已经保证了去重效果,如果用32位的话,存储空间会多一倍。建议16位

2)将生成的密文切割为16位的数组a,然后将a[0]的值与根节点下指向的节点值相比较,如果找到了一样的目标节点r[1],则将r[1]向下的节点与a[1]相比较,以此类推下去。如果未找到则新建一个值为当前比较字符,后续节点值为下一个字符的节点。

我们再来分析下时间和空间的复杂度:

1)空间分析,还是假设有50亿的url,普通存储需要300G,如果用16位的MD5进行加密后只需要四分之一的空间75G。再者,由于数的特殊性,不同密文直接在树结构中存在公用的路径,这又省去了一部分空间。假设去重树全部排满的话,我们理论上只需要5G的内存即可,是不是很屌!

2)时间分析,因为现在爬虫通常使用hash表来存储url以提高存储性能,因此我们将用普通的hash表来对比时间性能。哈希表查找时间分三部分,使用hash函数时间t1,查找冲突域的时间t2,字符串比较时间t3。最终的时间复杂度为O(n*t/m),n为总的url数量,m为hash表的长度,t为字符串比较时间,t1时间太短忽略不计。

接着看去重树,因为每个节点下最多只有16个子节点,所以我们的平均查找时间只需要16*t1*t2,t1表示映射时间,t2表示单个字符的比较时间。由于这两个时间都可以忽略不计,理论上说我们的时间复杂度接近O(1)!,是普通hash表查找的n/m倍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐