Nutch1.7学习笔记3:Injector源代码分析
作者:雨水,时间:2013-11-13 博客地址:http://blog.csdn.net/gobitan
Injector的主要功能
Injector的主要功能是将urls目录下的文本文件中的URL地址注入到CrawlDb中。
Injector类基本构成
(1) 三个主成员变量
nutchScoreMDName
nutchFetchIntervalMDName
nutchFixedFetchIntervalMDName
(2) 两个内部静态类
InjectMapper
InjectReducer
(3) 核心方法inject
除了以上主要部分,其他均可忽略。
内部类InjectMapper分析
该类实现了org.apache.hadoop.mapred.Mapper(K1,V1, K2, V2)接口,该接口包含一种重要的方法map(),它主要将输入的键值对映射为一个中间键值对。就是说,把原始输入转换为可以进行一下步工作的中间结果。
在InjectMapper的map中,它主要实现将指定url输入目录中包含url的文本文件映射为<url,CrawlDatum>的键值对。CrawlDatum包含了url的基本信息,如元数据(nutch.score,nutch.fetchInterval,nutch.fetchInterval.fixed),url的状态(如第一个状态为injected),获取时间等。
下面为元数据的提取过程,元数据之间是通过’\t’分隔的。每个url对应一个元数据,因此元数据与url位于同一行,在url的后面。
if(url.indexOf("\t")!=-1){
String[] splits = url.split("\t");
url = splits[0];
for(int s=1;s<splits.length;s++){
// find separation between name andvalue
int indexEquals =splits[s].indexOf("=");
if(indexEquals==-1) {
// skip anything without a =
continue;
}
String metaname = splits[s].substring(0, indexEquals);
String metavalue = splits[s].substring(indexEquals+1);
if(metaname.equals(nutchScoreMDName)){
try{
customScore = Float.parseFloat(metavalue);}
catch(NumberFormatException nfe){}
}
else if(metaname.equals(nutchFetchIntervalMDName)){
try{
customInterval = Integer.parseInt(metavalue);}
catch(NumberFormatException nfe){}
}
else if(metaname.equals(nutchFixedFetchIntervalMDName)){
try{
fixedInterval= Integer.parseInt(metavalue);}
catch(NumberFormatException nfe){}
}
elsemetadata.put(metaname,metavalue);
}
}
元数据提取完之后,就依次对Url进行normalize和filter. Normalize根据特定的规则进行处理 (这里不详细分析),filter主要是根据在regex-urlfilter.txt中定义的规则进行过滤。
最后将处理输出为<url,CrawlDatum>结构,将作为InjectReducer的输入。
内部类InjectReducer分析
该类实现了org.apache.hadoop.mapred.Reducer(K2,V2, K3, V3)接口,该接口包含一种重要的方法reduce(),它主要将原有的url和CrawlDb中原有的URL进行合并。合并时会受到两个配置参数的值的影响:db.injector.overwrite和db.injector.update。前者表示已经存在的CrawlDb记录是否会被injected的URL覆盖掉,后者表示已经存在的CrawlDb记录是否会被injected的URL更新,这两个的默认值均为false。
这意味着,默认的处理将是以injected的URL作为合并后的值。
核心方法inject
该方法中包含了Injector的主要工作流程:
第一步:将提取url并将其映射为<url,CrawlDatum>作为Hadoop的job进行执行,将结果存在mapred.temp.dir目录下。其中完成了对url种子文件中的url的规范化和按照预定义规则的过滤处理,主要由内部类InjectMapper来完成。
第二步:将第一步的输出与已经存在的crawldb进行合并,该任务依然是作为Hadoop的job来执行。它涉及到两个重要的类CrawlDbFilter和InjectReducer内部类。合并时,InjectReducer会将url的状态由injected更新为unfetched.
第三步:执行CrawlDb.install更改目录名称,第二步合并后的结果是以当时时间(毫秒)作为临时 文件名存储结果。Install将当前目录下的old删除,将current重命名为old,将第二步的临时文件名更新为current.
第四步:删除第一步留下的临时目录。