一个高性能的Web爬虫,必须有一个合适的网页容器。该容量最大的特点是要能够通过URL直接存取网页内容,并且要求有很高的性能,在一个千万级别的容器中存取一万次的时间应在1分钟左右(普通PC上)。
那么,有什么方式可以实现这个要求?
首先,我们想到文件系统,将URL编码(urlEncode,base64或hex都可以)后作为文件名直接存在文件系统的某个目录下,从而实现通过URL直接存取的目的。但这种方式管理上会有很大的问题(试过在一次删除十万个文件的朋友就知道会有多慢),会产生大量的小文件,在某些操作系统上会极大地降低文件系统的性能。
其次,放在数据库中,将URL单独存在一个字段里,为该字段建立索引,也可以实现按URL直接存取的目的,而且性能较好。但实际上这也不合适,几百万上千万的网页存放在数据库中,占用近TB的空间,必然要求对数据库有较大的投资,但从其他网站上采集的网页使用次数很少,并且极为廉价可再次获取,因此使用数据库很不划算。
也可以自己实现一个容器,直接管理持久层的裸设备,在裸设备上建立一套通过URL寻址的机制,将会获得最好的性能。但在容器量较小的情况这样又显很麻烦,因此采用拆衷的办法,在文件系统的基础上建立一组大文件和一组辅助文件,辅助文件实现通过URL定位该URL代表的网页在大文件中的位置,从页实现不随文件数量增长而性能变化的快速存取。以下将描述一个简洁的实现。
我们知道,一个HashMap在容量为10和容量为100000时通过Key存取一个元素的性能基本相当,因此可以在HashMap的基础上实现一个基于文件系统的FileMap。
第一步,我们直接照抄HashMap中的散列算法:
public static int hash(Object x, int length) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h & (length - 1);
}
假设length等于10000,那么传入一组URL通过hash()算法返回的值将基本平均分布在这1到10000,而不管这一组URL的具体内容到底是什么(URL之间要有差异,不能都相同或大部分相同,呵呵),这是整个实现最为关键的地方。在实际应用中length的值是随着容量增长而不变化的,每次扩容后都需要将所有URL重新计算散列值,大家可以参考HashMap中的实现。
第二步:存放文件内容
实现存放内容的方法:假如现在需要存放一个URL和它的内容,那么必须在value.dat的最后写入内容长度和内容本身(如果value.dat不存在,则需要先建立一个),并且返回一个内容长度起始字节在value.dat中的起始地址。
第三步:存放键值
实现存放键值的算法:得到内容的起始地址,计算[起始地址+URL]的长度,将该长度和[起始地址+URL]写入键值辅助文件key.dat的最后(如果key.dat不存在,则需要先建立一个),并且返回该长度起始字节在key.dat的地址。
第四步:存放散列值与键值地址的对应关系
实现存放散列值与键值地址对应关系的算法:得到键值的起始地址后(地址长度为4字节,即为long类型的长度),通过hash()计算URL的散列值,假设散列值为3000的话,则将该地址写入地址辅助文件address.idx的第12000-12004个字节。(以后再说散列冲突的情况)
第五步:取URL内容的
实现取URL内容的算法:假设URL已经存入FileMap,当需要通过URL取内容时,步骤如上:通过hash()计算URL的散列值,通过散列值从address.idx中取键值在key.dat中的地址,通过键值中内容在value.dat中的地址,即可取到URL对应的内容了。
第六步:解决散列冲突
hash()能将一组URL基本平均地分布在一块地址上,但不可避免地会出现散列冲突的情况,即多个不同的URL获得同一个散列值的情况,这时候第一个存入的URL将直接写入address.idx中散列值对应的地址,其他的URL存入时需要将本身的键值地址写入第一个URL在key.dat的记录的末尾,以便存取时能够通过第一个URL找到其他散列值相同的URL,从面解决散列冲突的问题。
以上六步是实现一个TB级别的容器可以选择的比较简洁的过程,实际运用中还需要解决value.dat过大的问题(有时操作系统对文件大小有限制,必须形成value0.data,value1.data,value2.data等一组value文件,从而使得寻址进一步复杂),解决重新散列的问题,解决压缩存取的问题。
虽然存取一个URL使用了3个文件,但因address.idx和key.dat的体积都很小,使用时又都是直接定位,并且因频繁被使用被磁盘的Cache以及操作系统的Cache缓存,时间性能消耗是非常小的。
-------Zving Soft-------
ZCMS(泽元内容管理系统),泽元软件出品,免费下载,不限用途。
欢迎试用:
http://demo.zving.com
分享到:
相关推荐
A2ZCMS - CI ====== 基于 Codeigniter 2.2.0 的 A2Z CMS A2Z CMS 特点: 代码点火器 2.2.0 推特引导程序 3.0.0 后端 自动安装和设置网站。 用户和角色管理。 查看用户登录历史。 管理博客帖子和评论。 管理...
(简称ZCMS) 是一套基于J2EE和插件技术的、面向高端用户的网站内容管理软件,集内容规划、内容创作、内容编辑、内容审核、基于模板的内容发布等功能于一身,并提供互动组件、可视化专题、内容采集、内容检索、访问...
【ZCMS弹出框架最新版3.0】是一款专为ZCMS内容管理系统设计的弹出对话框组件,其核心是zDialog3.0,这是zDialog的最新升级版本。zDialog作为ZCMS中的一个关键模块,它极大地提升了用户体验,使得在进行页面交互时...
“Tomcat”是一个开源的Java Servlet容器,常用于部署和运行Web应用程序。虽然zcms是一个桌面应用,但考虑到它可能包含Web服务或Web接口,用于管理和上传待转码的视频文件,因此Tomcat可能作为其后端服务的一部分,...
ZCMS的所有操作均在Web页面中进行,包括内容编辑、系统配置和日常维护等。这种设计极大地降低了用户的使用门槛,使非技术人员也能轻松上手。用户可以在浏览器中直接编辑文档,包括字体、字号、对齐方式、图片插入、...
ZCMS系统 ZCMS(Zhacai Content Management System)是由Zhacai学习并开发的一个基于Vue和JQuery的内容管理系统。此为WEB应用技术的期末大作业,遵循GPL-3.0协议开源,欢迎提出改进意见。 ZCMS (Zhacai Content ...
泽元网站内容管理系统 (简称ZCMS) 是一套基于J2EE和 AJAX 技术的企业级网站内容管理软件(CMS),集站点管理、内容创作、内容审核、基于模板的内容发布、内容采集、内容检 索、多媒体内容管理于一身。ZCMS 允许非专业...
(简称ZCMS) 是一套基于J2EE和插件技术的、面向高端用户的网站内容管理软件,集内容规划、内容创作、内容编辑、内容审核、基于模板的内容发布等功能于一身,并提供互动组件、可视化专题、内容采集、内容检索、访问...
- **5.6.1 新建WEB采集任务**:创建新的数据采集任务。 - **5.6.2 修改WEB采集任务**:编辑已有的采集任务。 - **5.6.3 删除WEB采集任务**:移除不再需要的任务。 - **5.6.4 清空采集数据**:清除采集的历史数据...
ZCMS弹出框架最新版V2.3是一个专为ZCMS(泽元内容管理系统)设计的弹出对话框解决方案,其核心组件为zDialog2.3。这个框架旨在提升用户体验,提供更加灵活、功能丰富的弹窗功能,适用于各种管理系统的交互需求。 ...
《基于ThinkPHP3.2的ZCMS系统详解》 ZCMS,全称为"Zen Content Management System",是一款基于ThinkPHP3.2框架构建的开源内容管理系统。作为一个全面的功能性CMS,它为开发者提供了丰富的功能模块和高度的可扩展性...
### ZCMS系统中文章的相关设置详细介绍 #### 一、ZCMS系统概述 ZCMS是一款功能强大的内容管理系统(Content Management System),广泛应用于网站建设和管理之中。它提供了丰富的工具和选项,帮助用户轻松创建、编辑...
【标题】"zcms.zip_jsp毕业设计_zcms"是一个基于JSP技术的毕业设计项目,主要用于构建一个在线BBS论坛系统。这个项目对于初学者来说是一个很好的学习资源,特别是那些正在学习JSP编程的学生。它展示了如何使用JSP来...