Nutch 1.3 学习笔记 8 LinkDb
----------------------------
这里主要是分析一下org.apache.nutch.crawl.LinkDb,它主要是用计算反向链接。
本地的运行结果为:
+ 分析新输入的segment目录,产生新的反向链接库
+ 把新产生的反向链接库与原来的库进行合并
下面来看一下createJob都做了些什么:
下面来看一下LinkDb中的map做了些什么,这个方法主要是从toUrl=>fromUrl建立一个对应关系,这个有点像倒排索引中的TermId=>DocId
而LinkDbMerger这个类实现了reducer接口,主要是收集指定个数的同一个toUrl的fromUrl,这个指定的个数可能通过设置db.max.inlinks来设定。
我们再看一下createMergeJob做了些什么:
下面是本机运行的结果:
下面是输出output2目录中文件的部分内容,可以看到,这里一个<key,value>对,key是toUrl,value是fromUrl
这个readlinkdb也是用了一个MP任务,输入格式为SequenceFileInputFormat,输出格式为TextOutput,Map-Reducer都是用的默认的。
其实这里的合并就是调用上面分析的LinkDbMerger中的createMergeJob方法
5. 总结
这里主要是对于parse_data目录中分析出来的外链接进行反向链接的计算,在下面计算链接分数的时候会用到这些反向链接。
----------------------------
这里主要是分析一下org.apache.nutch.crawl.LinkDb,它主要是用计算反向链接。
1. 运行命令 bin/nutch invertlinks
帮助参数说明:Usage: LinkDb <linkdb> (-dir <segmentsDir> | <seg1> <seg2> ...) [-force] [-noNormalize] [-noFilter]
linkdb output LinkDb to create or update
-dir segmentsDir parent directory of several segments, OR
seg1 seg2 ... list of segment directories
-force force update even if LinkDb appears to be locked (CAUTION advised)
-noNormalize don't normalize link URLs
-noFilter don't apply URLFilters to link URLs
本地的运行结果为:
lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch invertlinks db/linkdb/ db/segments/20110822105243/
LinkDb: starting at 2011-08-29 09:21:36
LinkDb: linkdb: db/linkdb
LinkDb: URL normalize: true
LinkDb: URL filter: true
LinkDb: adding segment: db/segments/20110822105243 // 加入新的segment库
LinkDb: merging with existing linkdb: db/linkdb // 与原因的库进行合并
LinkDb: finished at 2011-08-29 09:21:40, elapsed: 00:00:03
2. LinkDb主要源代码分析
在LinkDb主要是调用一个invert方法,这个方法做了两件事,+ 分析新输入的segment目录,产生新的反向链接库
+ 把新产生的反向链接库与原来的库进行合并
2.1 分析新输入的segment目录,主要代码如下:
// 新建立一个MP任务
JobConf job = LinkDb.createJob(getConf(), linkDb, normalize, filter);
// 添加目录到输入路径,这里可能有多个输入路径, parse_data
for (int i = 0; i < segments.length; i++) {
if (LOG.isInfoEnabled()) {
LOG.info("LinkDb: adding segment: " + segments[i]);
}
FileInputFormat.addInputPath(job, new Path(segments[i], ParseData.DIR_NAME));
}
// 提交MP任务
try {
JobClient.runJob(job);
} catch (IOException e) {
LockUtil.removeLockFile(fs, lock);
throw e;
}
下面来看一下createJob都做了些什么:
private static JobConf createJob(Configuration config, Path linkDb, boolean normalize, boolean filter) {
// 新成一个临时的目录
Path newLinkDb =
new Path("linkdb-" +
Integer.toString(new Random().nextInt(Integer.MAX_VALUE)));
JobConf job = new NutchJob(config);
job.setJobName("linkdb " + linkDb);
// 设置输出格式
job.setInputFormat(SequenceFileInputFormat.class);
// 配置Map,Combiner,Reducer方法
job.setMapperClass(LinkDb.class);
job.setCombinerClass(LinkDbMerger.class);
// 如果配置了过滤或者规格化,并且没有找到老的linkdb目录,好就以filter和normalize进行配置
// if we don't run the mergeJob, perform normalization/filtering now
if (normalize || filter) {
try {
FileSystem fs = FileSystem.get(config);
if (!fs.exists(linkDb)) {
job.setBoolean(LinkDbFilter.URL_FILTERING, filter);
job.setBoolean(LinkDbFilter.URL_NORMALIZING, normalize);
}
} catch (Exception e) {
LOG.warn("LinkDb createJob: " + e);
}
}
job.setReducerClass(LinkDbMerger.class);
// 配置MP输出路径
FileOutputFormat.setOutputPath(job, newLinkDb);
// 配置输出格式
job.setOutputFormat(MapFileOutputFormat.class);
// 对map输出使用压缩,以减少Reducer的输入压力
job.setBoolean("mapred.output.compress", true);
// 配置<key,value>的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Inlinks.class);
return job;
}
下面来看一下LinkDb中的map做了些什么,这个方法主要是从toUrl=>fromUrl建立一个对应关系,这个有点像倒排索引中的TermId=>DocId
而LinkDbMerger这个类实现了reducer接口,主要是收集指定个数的同一个toUrl的fromUrl,这个指定的个数可能通过设置db.max.inlinks来设定。
2.2 把新产生的反向链接库与老的库进行合并,主要代码如下:
if (fs.exists(currentLinkDb)) { // 如果存在老的反向链接库,就进行合并
if (LOG.isInfoEnabled()) {
LOG.info("LinkDb: merging with existing linkdb: " + linkDb);
}
// try to merge
//
Path newLinkDb = FileOutputFormat.getOutputPath(job);
job = LinkDbMerger.createMergeJob(getConf(), linkDb, normalize, filter);
// 加入输入路径
FileInputFormat.addInputPath(job, currentLinkDb);
FileInputFormat.addInputPath(job, newLinkDb);
try {
JobClient.runJob(job);
} catch (IOException e) {
LockUtil.removeLockFile(fs, lock);
fs.delete(newLinkDb, true);
throw e;
}
fs.delete(newLinkDb, true);
}
LinkDb.install(job, linkDb); // 安装新生成的反向链接库
我们再看一下createMergeJob做了些什么:
public static JobConf createMergeJob(Configuration config, Path linkDb, boolean normalize, boolean filter) {
// 生成一个临时目录
Path newLinkDb =
new Path("linkdb-merge-" +
Integer.toString(new Random().nextInt(Integer.MAX_VALUE)));
JobConf job = new NutchJob(config);
job.setJobName("linkdb merge " + linkDb);
// 配置个输出格式
job.setInputFormat(SequenceFileInputFormat.class);
// 配置Map与Reducer方法,这里的Reducer方法与上面的一样,用于对相同key(toUrl)的values进行聚合
// 然后输出指定个数的value,而这里的LinkDbFilter应该是对key与value所对应的url进行过滤与正规化
job.setMapperClass(LinkDbFilter.class);
job.setBoolean(LinkDbFilter.URL_NORMALIZING, normalize);
job.setBoolean(LinkDbFilter.URL_FILTERING, filter);
job.setReducerClass(LinkDbMerger.class);
// 配置输出路径
FileOutputFormat.setOutputPath(job, newLinkDb);
job.setOutputFormat(MapFileOutputFormat.class);
job.setBoolean("mapred.output.compress", true);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Inlinks.class);
return job;
}
3. bin/nutch readlinkdb 分析
主要是用于下载linkdb的内容到指定的目录,帮助如下:
Usage: LinkDbReader <linkdb> {-dump <out_dir> | -url <url>)
-dump <out_dir> dump whole link db to a text file in <out_dir>
-url <url> print information about <url> to System.out
下面是本机运行的结果:
lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch readlinkdb db/linkdb/ -dump output2
LinkDb dump: starting at 2011-08-29 09:54:08
LinkDb dump: db: db/linkdb/
LinkDb dump: finished at 2011-08-29 09:54:09, elapsed: 00:00:01
下面是输出output2目录中文件的部分内容,可以看到,这里一个<key,value>对,key是toUrl,value是fromUrl
lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ head output2/part-00000
http://baike.baidu.com/ Inlinks:
fromUrl: http://www.baidu.com/ anchor: 百科
http://hi.baidu.com/ Inlinks:
fromUrl: http://www.baidu.com/ anchor: 空间
http://hi.baidu.com/baidu/ Inlinks:
fromUrl: http://www.baidu.com/ anchor:
http://home.baidu.com/ Inlinks:
这个readlinkdb也是用了一个MP任务,输入格式为SequenceFileInputFormat,输出格式为TextOutput,Map-Reducer都是用的默认的。
4. bin/nutch mergelinkdb 分析
主要是用来合并个不同的linkdb数据库的
Usage: LinkDbMerger <output_linkdb> <linkdb1> [<linkdb2> <linkdb3> ...] [-normalize] [-filter]
output_linkdb output LinkDb
linkdb1 ... input LinkDb-s (single input LinkDb is ok)
-normalize use URLNormalizer on both fromUrls and toUrls in linkdb(s) (usually not needed)
-filter use URLFilters on both fromUrls and toUrls in linkdb(s)
其实这里的合并就是调用上面分析的LinkDbMerger中的createMergeJob方法
5. 总结
这里主要是对于parse_data目录中分析出来的外链接进行反向链接的计算,在下面计算链接分数的时候会用到这些反向链接。