前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nutch源码阅读进程1---inject

Nutch源码阅读进程1---inject

作者头像
JackieZheng
发布2018-01-08 15:41:23
6900
发布2018-01-08 15:41:23
举报
文章被收录于专栏:JackieZhengJackieZheng

最近在Ubuntu下配置好了nutch和solr的环境,也用nutch爬取了一些网页,通过solr界面呈现,也过了一把自己建立小搜索引擎的瘾,现在该静下心来好好看看nutch的源码了,先从Inject开始吧~~~

1.从crawl.java的main函数进入,执行: Configuration conf = NutchConfiguration.create();

再进入NutchConfiguration(NutchConfiguration负责加载管理nutch的配置文件信息,该类继承自Configuration,继承了Configuration所有功能,加载配置文件功能也是继承自Configuration类)类的create方法,执行:Configuration conf = new Configuration();从执行结果可以看出在类Configuration的静态代码块中代码 addDefaultResource("core-default.xml");addDefaultResource("core-site.xml");可以看出是加载了core-default.xml, core-site.xml两个文件;

2.通过Configuration完成指定配置文件的加载,加载后的conf为:Configuration: core-default.xml, core-site.xml, nutch-default.xml, nutch-site.xml共四个配置文件;

之后回到crawl的main函数中执行:int res = ToolRunner.run(conf, new Crawl(), args);参数conf是刚刚加载好配置文件的Configuration对象,Crawl是要执行的对象类,args是用户输入的参数串,这里是使用hadoop的工具类ToolRunner运行实例Crawl类,即进入核心的爬虫模块;

然后进入ToolRunner类的run()方法,第一步就是利用类GenericOptionsParser(备注:GenericOptionsParser是hadoop框架中解析命令行参数的基本类。它能够辨别一些标准的命令行参数,能够使应用程序轻易地指定namenode,jobtracker,以及其他额外的配置资源)对输入的命令行参数args(如[urls, -dir, crawl20140724, -depth, 2, -threads, 8, -topN, 100])进行解析,再执行:String[] toolArgs = parser.getRemainingArgs();获得解析后的参数数组(比如[urls, -dir, crawl20140724, -depth, 2, -threads, 8, -topN, 100]);

然后执行返回语句:return tool.run(toolArgs);这里的tool就是Crawl类的对象,run()方法也是Crawl类中的run方法;

3.解析完用户的输入参数后,执行Crawl类的run()方法。第一步就是配置程序的默认参数,如果用户没有相应的参数赋值就使用这些默认的参数。注意这里有一点编程思想可以借鉴:

int threads = getConf().getInt("fetcher.threads.fetch", 10);该行代码的getInt方法具体如下:

public int getInt(String name, int defaultValue) { String valueString = get(name);//get的核心代码为:return substituteVars(getProps().getProperty(name));,主要是从配置文件中查找有没有相应的赋值 if (valueString == null)     return defaultValue;//如果配置文件中没有赋值,则valueString为null,这是getInt方法的返回值就是默认值10,即defaultValue

代码语言:js
复制

try {
    String hexString = getHexDigits(valueString);
    if (hexString != null) {
        return Integer.parseInt(hexString, 16);
    }
    return Integer.parseInt(valueString);
} catch (NumberFormatException e) {
    return defaultValue;
    }
}

后面就是遍历args参数串,如果发现匹配的则对相应的变量赋值

第二步初始化jobconf:JobConf job = new NutchJob(getConf());执行后job为Configuration: core-default.xml, core-site.xml, mapred-default.xml, mapred-site.xml, nutch-default.xml, nutch-site.xml等于讲conf的加入后还在JobConf类中的静态代码块中加入了配置文件mapred-default.xml, mapred-site.xml。

后面又初始化文件系统:FileSystem fs = FileSystem.get(job);下面是网上关于FileSystem的介绍(备注:

就像上节所说的,有时候我们无法通过设置URLStreamHandlerFactory方法的方式来通过URL读取数据,这时FIleSystem API就派上用场了。  Hadoop文件系统中的文件是用Hadoop的Path对象来表示的(而不是java中的java.io.File对象,因为它的语义太接近于本地文件系统了)。你可以把一个Path对象看做Hadoop文件系统中的某一个URL,如上例中的“hdfs://localhost/user/tom/quangle.txt”。  Filesystem是一个通用的文件系统API,所以使用它的第一步就是先抽取出它的一个实例出来——在这个例子中是HDFS。下面列出了几个Filesystem的用于抽取Filesystem实例的几个静态方法:

public static FileSystem get(Configuration conf) throws IOException public static FileSystem get(URI uri, Configuration conf) throws IOException public static FileSystem get(URI uri, Configuration conf, String user) throws IOException

一个Configuration对象封装了客户端或服务器端的配置信息,这些配置信息是通过从conf/core-size.xml之类的配置文件中读取出来的名值对来设置的。下面我们一一说明上面的三个方法:  1)第一个方法返回一个默认的文件系统(在conf/core-site.xml中通过fs.default.name来指定的,如果在conf/core-site.xml中没有设置则返回本地文件系统)。  2)第二个方法通过uri来指定要返回的文件系统(例如,如果uri是上个测试例子中的hdfs://localhost/user/tom/quangle.txt,也即以hdfs标识开头,那么就返回一个hdfs文件系统,如果uri中没有相应的标识则返回本地文件系统)。  3)第三个方法返回文件系统的机理同(2)是相同的,但它同时又限定了该文件系统的用户,这在安全方面是很重要的。

4)初始化jobconf和filesystem后,主要是一些参数的界面输出,以及明确临时文件的存放位置并初始化nutch爬取的几个流程类inject、generate、fetch、parse和update等;

然后执行:injector.inject(crawlDb, rootUrlDir);初始化CrawlDb,实现将url转换为指定格式的输入;

进入该方法后,设置一些的参数,包括输入输出,mapper类等,最后提交job交由mapreduce执行,JobClient.runJob(sortJob);

通过调试模式看到,程序是先进入了Inject类的configurable方法进行了一些参数的赋值,然后跳到Inject类的map方法,该方法主要包括:读取url,对url进行分割,url规范化和过滤的操作,然后返回一个处理后的url;

然后再生声明CrawlDatum类:CrawlDatum datum = new CrawlDatum(CrawlDatum.STATUS_INJECTED, customInterval);,最终是要将输入数据转换为<Text,CrawlDatum >格式的,设置一些url的初始化数据(在ScroingFilters类中的injectedScore方法可以看到的datum值为:

Version: 7 Status: 66 (injected) Fetch time: Thu Jul 24 23:04:37 CST 2014 Modified time: Thu Jan 01 08:00:00 CST 1970 Retries since fetch: 0 Retry interval: 2592000 seconds (30 days) Score: 1.0 Signature: null Metadata:  )

通过调试看到程序执行完Inject的map方法后会跳到MapRunner中的run方法,部分代码如下:

public void run(RecordReader<K1, V1> input, OutputCollector<K2, V2> output, Reporter reporter) throws IOException { try { // allocate key & value instances that are re-used for all entries K1 key = input.createKey(); V1 value = input.createValue(); while (input.next(key, value)) {

……

其中in就是url存放的文件的读入流;

然后又跳入LoadJobRunner类中执行代码,在这里会执行:ReduceTask reduce = new ReduceTask(systemJobFile.toString(), reduceId, 0, mapIds.size(), 1);……reduce.run(localConf, this);……的代码

之后会有一些输入输出流的关闭以及杀死一些线程,还有删除本地的一些临时文件

以上便是nutch的Inject部分的实现流程。

参考博文:http://blog.csdn.net/amuseme_lu/article/details/6713386

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-07-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档