最近和寝室的同学一起搭建了Hadoop的集群,实现了一个简易的本地搜索引擎,并且将其开源到了github上:https://github.com/ifuding/search-1047,接下来的几篇博文将对这个项目及其代码作一些详细的描述。
搜索原理概述
“搜索”,简而言之就是要分析用户输入然后输出给用户已经排好序的URL集合。一个简单的实现所需要的排序依据主要就是文本检索以及url的PageRank值。
PageRank
PageRank算法有很多文章对其进行讲解,其模型类似一个马尔科夫链。如果一个高PageRank值的网页1指向了另一个网页2,则可以认为网页2的PageRank值也会相应的变高。
假设有n个src网页指向一个target网页,则我们认为:
Pr[target]=1-dampFac+dampFac*sum{Pr[src]/OutlinkNum[src]}
其中,dampFac是为了防止死链和陷阱的。
所谓死链就是所有的url指向了一个url,但是此url没有出链,则最后所有网页的Pr会收敛到0。如果此url有指向自己的循环,则最后除了此url其它url的Pr的值都会收敛到0。
所以在公式里面加入了阻尼因子dampFac,模拟上网者的真实行为,即你可以以dampFac的概率选择进入此网页,或者以1-dampFac的概率离开此网页。借此避免以上两种错误的收敛情况。
文本检索
文本检索有专门的NLP分析方法,在本项目中暂时采用简单的文本匹配和计数技术。
Nutch爬虫
Nutch的开发就是为了搜索引擎,Hadoop最开始只是Nutch的一个子项目。
在此次的项目中我们没有过多地关注Nutch的部分,只是使用了Nutch爬取的一部分输出,准确的说是url的链接信息“linkdb”和网页文本信息“parse_text”。因为它们都是MapFile的文件格式,为了更方便地作为Mapper的输入我们需要对以上文件做一些必要的转换和脚本处理。
Hadoop
Hadoop实现了分布式文件系统HDFS以及基于Mapreduce的分布式计算。
当你在Linux下安装好Hadoop,以伪分布式打开Hadoop后,利用jps查看可以看到如下6个进程,除了Jps其它5个就是Hadoop守护进程:
14779 DataNode
15322 NodeManager
14657 NameNode
15194 ResourceManager
17656 Jps
14979 SecondaryNameNode
其中NameNode,SecondaryNameNode以及DataNode就是负责HDFS的进程,NameNode保存文件的分片索引,管理所有的文件目录,SecondaryNameNode是它的副本。DataNode只保存分片的文件,并且有分片文件的节点才会执行Mapper和Reducer。
而ResourceManager和NodeManger就是控制job和Task的。运行一次Mapreduce就是一次job,而job又分很多次Task来执行。每个task又分为map task和reduce task。
详细的讲解以及Mapreduce job的运行机制可参考《Hadoop权威指南》。
有了以上基础知识,可按照以下步骤具体实现:
- 安装好Nuch和Hadoop(没有Linux基础的同学,说起来都是泪)
- 利用Hadoop运行样例程序,可参考:http://blog.csdn.net/dingzuoer/article/details/44725869
- 利用Nutch爬取网页,生成需要的linkdb和parse_text。
- 接下来就需要为了实现PageRank作一些必要的文本预处理,可参考我下一篇博文具体分析。。。