|
1. Inject是干嘛的?
在Nutch中Inject是用来把文本格式的url列表注入到抓取数据库中,一般是用来引导系统的初始化。
这里的文本格式如下:
http://www.nutch.org/ \t nutch.score=10 \t nutch.fetchInterval=2592000 \t userType=open_source
这里的url与其元数据之间用Tab隔开,这里有两个保留的元数据,如下
nutch.score : 表示特定url的分数
nutch.fetchInterval : 表示特定url的抓取间隔,单位为毫秒
Inject注入后生成的数据库为二进制结构,是Hadoop的MapSequenceFileOutputFormat格式
2. Inject运行命令
在本地运行后的输出结果如下:
Injector: starting at 2011-08-23 10:14:10
Injector: crawlDb: db/crawldb
Injector: urlDir: urls
Injector: Converting injected urls to crawl db entries.
Injector: Merging injected urls into crawl db.
Injector: finished at 2011-08-23 10:14:12, elapsed: 00:00:02
你可以用如下命令来查看其数据库内容
bin/nutch readdb -stats -sort
在本机的输出如下:
rawlDb statistics start: db/crawldb
Statistics for CrawlDb: db/crawldb
TOTAL urls: 1
retry 0: 1
min score: 1.0
avg score: 1.0
max score: 1.0
status 1 (db_unfetched): 1
www.baidu.com : 1
CrawlDb statistics: done
3. Inject源代码分析
我们知道Injector.java在Nutch源代码中的位置为org.apache.nutch.crawl.Injector.java
其中有一个main入口函数,使用Hadoop的工具类ToolRunner来运行其实例
但其是终入口函数还是void inject(Path crawlDb, Path urlDir)
其中有两个MP任务,第一个主要是把文件格式的输入转换成格式的输出,这里的
CrawlDatum是Nutch对于单个抓取url对象的一个抽象,其中有很多url的相关信息
第二个MP主要是把上面新生成的输出与旧的CrawlDb数据进行合并,生成一个新的CrawlDb
3.1 对于Inject中第一个MP任务的分析
第一个MP任务主要代码如下:
JobConf sortJob = new NutchJob(getConf()); // 生成一个Nutch的配置抽象
sortJob.setJobName("inject " + urlDir);
FileInputFormat.addInputPath(sortJob, urlDir); // 设置InputFormat,这里为FileInputFormat,这里要注意的是可以调用多次addInputPath这个方法,效果是会有多个输入源
sortJob.setMapperClass(InjectMapper.class); // 这里设置了Mapper方法,主要是用于解析、过滤和规格化url文本,把其转换成格式
FileOutputFormat.setOutputPath(sortJob, tempDir); // 这里定义了一个输出路径,这里的tempDir=mapred.temp.dir/inject-temp-Random()
sortJob.setOutputFormat(SequenceFileOutputFormat.class); // 这里配置了输出格式,这里为SequenceFileOutputFormat,这是MP的一种二进制输出结构
sortJob.setOutputKeyClass(Text.class); // 这里配置了MP的输出的类型,这里为
sortJob.setOutputValueClass(CrawlDatum.class);
sortJob.setLong("injector.current.time", System.currentTimeMillis());
JobClient.runJob(sortJob); // 这里用于提交任务到JobTracker,让其运行任务
这里对InjectMapper中的主要代码进行分析:
这个类主要用于对url进行解析、过滤和规格化
public void map(WritableComparable key, Text value,
OutputCollector output, Reporter reporter)
throws IOException {
String url = value.toString(); // value is line of text
if (url != null && url.trim().startsWith("#")) { // 这里以#号开头的文本就过滤
/* Ignore line that start with # */
return;
}
// if tabs : metadata that could be stored
// must be name=value and separated by \t
float customScore = -1f;
int customInterval = interval;
Map metadata = new TreeMap(); // 设置属性的一个容器
if (url.indexOf("\t")!=-1){
String[] splits = url.split("\t"); // 对一行文本进行切分
url = splits[0];
for (int s=1;s
|
|