网络爬虫项目开发日志(七): 基于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倍。
本文仅做研究交流用,非工业化标准,各位大神不喜勿喷哈
--引言--
爬虫系统在面对海量网页数据时,会因为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倍。
相关文章推荐
- 网络爬虫项目开发日志(二):爬虫架构设计
- 网络爬虫项目开发日志(一):关于爬虫项目所涉及的领域知识
- 网络爬虫项目开发日志(三):爬虫上线准备
- 基于Hadoop开发网络云盘系统架构设计方案第一稿
- 基于Hadoop开发网络云盘系统客户端界面设计初稿
- 基于Scrapy分布式爬虫的开发与设计
- FreeBook 基于 MVP 模式开发的带缓存网络爬虫,采用最流行框架搭建,干货多多
- 基于Hadoop开发网络云盘系统架构设计方案第一稿
- 基于BBB的4轮移动轮式机器人系统设计与实现(六)--网络通信类的开发
- Python大型网络爬虫项目开发实战
- 一只简单的网络爬虫(基于linux C/C++)————读取命令行参数及日志宏设计
- 基于Hadoop开发网络云盘系统架构设计方案
- 【项目】07年度科创项目“智能施工网络优化软件开发”结题书、源代码发布
- jphone项目设计介绍(一个基于C++的应用程序框架以及软电话和日志服务器应用)
- 记录一个关于互联网、网页设计、Web开发、服务器运维优化、项目管理、网站运营、网站安全的网站
- 基于Hadoop开发网络云盘系统客户端界面设计初稿
- Linux企业级项目实践之网络爬虫(3)——设计自己的网络爬虫
- 安卓项目开发之网页电话---基于webrtc的网络电话
- 基于MVC模式的电商项目开发系列之2:数据库设计
- 基于MVP模式开发的带缓存网络爬虫,采用最流行框架搭建,干货多多