文洲 2013-08-04
http://www.chinacloud.cn/show.aspx?id=62&cid=12
Nutch是最早用MapReduce的项目 (Hadoop其实原来是Nutch的一部分),Nutch的plugin机制吸取了eclipse的plugin设计思路。在Nutch中 MapReduce编程方式占据了其核心的结构大部分。从插入url列表(Inject),生成抓取列表(Generate),抓取内容(Fetch), 分析处理内容(Parse),更新Crawl DB库(Update ),转化链接(Invert Links)一直到建立索引(Index)都是采用MapReduce来完成的。查看Nutch的源代码我们能够学到更多的 如何用MapReduce来处理我们编程中所遇到的问题。
Nutch从获取下载列表到建立索引的过程:
插入url列表到Crawl DB,引导下面的抓取程序 循环: – 从Crawl DB生成一些url列表; – 抓取内容; – 分析处理抓取的内容; – 更新Crawl DB库. 转化每个页面中外部对它的链接 建立索引
具体技术实现细节:
1。插入url列表(Inject)
MapReduce程序1: 目标:转换input输入为CrawlDatum格式. 输入: url文件 Map(line) → <url, CrawlDatum> Reduce()合并多重的Url. 输出:临时的CrawlDatum文件. MapReduce2: 目标:合并上一步产生的临时文件到新的DB 输入: 上次MapReduce输出的CrawlDatum Map()过滤重复的url. Reduce: 合并两个CrawlDatum到一个新的DB 输出:CrawlDatum
2。生成抓取列表(Generate)
MapReduce程序1: 目标:选择抓取列表 输入: Crawl DB 文件 Map() → 如果抓取当前时间大于现在时间 ,抓换成 <CrawlDatum, url>格式. 分发器(Partition) :用url的host保证同一个站点分发到同一个Reduce程序上. Reduce:取最顶部的N个链接. MapReduce程序2: 目标:准备抓取 Map() 抓换成 <url,CrawlDatum,>格式 分发器(Partition) :用url的host 输出:<url,CrawlDatum>文件
3。抓取内容(Fetch)
MapReduce: 目标:抓取内容 输入: <url,CrawlDatum>, 按host划分, 按hash排序 Map(url,CrawlDatum) → 输出<url, FetcherOutput> 多线程, 调用Nutch的抓取协议插件,抓取输出<CrawlDatum, Content> 输出: <url,CrawlDatum>, <url,Content>两个文件
4。分析处理内容(Parse)
MapReduce: 目标:处理抓取的能容 输入: 抓取的<url, Content> Map(url, Content) → <url, Parse> 调用Nutch的解析插件,输出处理完的格式是<ParseText, ParseData> 输出: <url,ParseText>, <url,ParseData><url,CrawlDatum>.
5。更新Crawl DB库(Update )
MapReduce: 目标: 整合 fetch和parse到DB中 输入:<url,CrawlDatum> 现有的db加上fetch和parse的输出,合并上面3个DB为一个新的DB 输出: 新的抓取DB
6。转化链接(Invert Links)
MapReduce: 目标:统计外部页面对本页面链接 输入: <url,ParseData>, 包含页面往外的链接 Map(srcUrl, ParseData> → <destUrl, Inlinks> 搜集外部对本页面的链接Inlinks格式:<srcUrl, anchorText> Reduce() 添加inlinks 输出: <url, Inlinks>
7。建立索引(Index)
MapReduce: 目标:生成Lucene索引 输入: 多种文件格式 parse处理完的<url, ParseData> 提取title, metadata信息等 parse处理完的<url, ParseText> 提取text内容 转换链接处理完的<url, Inlinks> 提取anchors 抓取内容处理完的<url, CrawlDatum> 提取抓取时间. Map() 用ObjectWritable包裹上面的内容 Reduce() 调用Nutch的索引插件,生成Lucene Document文档 输出: 输出Lucene索引