最近在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
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

友情赞助

如果你觉得博主的文章对你那么一点小帮助,恰巧你又有想打赏博主的小冲动,那么事不宜迟,赶紧扫一扫,小额地赞助下,攒个奶粉钱,也是让博主有动力继续努力,写出更好的文章^^。

    1. 支付宝                          2. 微信

                      

Nutch源码阅读进程1---inject的更多相关文章

  1. Nutch源码阅读进程5---updatedb

    看nutch的源码仿佛就是一场谍战片,而构成这精彩绝伦的谍战剧情的就是nutch的每一个从inject->generate->fetch->parse->update的环节,首 ...

  2. Nutch源码阅读进程3---fetch

    走了一遍Inject和Generate,基本了解了nutch在执行爬取前的一些前期预热工作,包括url的过滤.规则化.分值计算以及其与mapreduce的联系紧密性等,自我感觉nutch的整个流程是很 ...

  3. Nutch源码阅读进程2---Generate

    继之前仓促走完nutch的第一个流程Inject后,再次起航,Debug模式走起,进入第二个预热阶段Generate~~~   上期回顾:Inject主要是将爬取列表中的url转换为指定格式<T ...

  4. Nutch源码阅读进程3

    走了一遍Inject和Generate,基本了解了nutch在执行爬取前的一些前期预热工作,包括url的过滤.规则化.分值计算以及其与mapreduce的联系紧密性等,自我感觉nutch的整个流程是很 ...

  5. Nutch源码阅读进程5

    看nutch的源码仿佛就是一场谍战片,而构成这精彩绝伦的谍战剧情的就是nutch的每一个从inject->generate->fetch->parse->update的环节,首 ...

  6. Nutch源码阅读进程4---parseSegment

    前面依次看了nutch的准备工作inject和generate部分,抓取的fetch部分的代码,趁热打铁,我们下面来一睹parse即页面解析部分的代码,这块代码主要是集中在ParseSegment类里 ...

  7. Nutch源码阅读进程4

    前面依次看了nutch的准备工作inject和generate部分,抓取的fetch部分的代码,趁热打铁,我们下面来一睹parse即页面解析部分的代码,这块代码主要是集中在ParseSegment类里 ...

  8. Linux 源码阅读 进程管理

    Linux 源码阅读 进程管理 版本:2.6.24 1.准备知识 1.1 Linux系统中,进程是最小的调度单位: 1.2 PCB数据结构:task_struct (Location:linux-2. ...

  9. golang martini 源码阅读笔记之inject

    martini是go语言写的一个超级轻量的web开源框架,具体源码可在github搜索找到.13年那会开始接触go语言时有稍微看过这个框架,由于之后没有继续使用go就慢慢忽略了,最近由于手头项目可能会 ...

随机推荐

  1. (转)JQuery上传插件Uploadify使用详解

    原文地址:http://www.cnblogs.com/oec2003/archive/2010/01/06/1640027.html Uploadify是JQuery的一个上传插件,实现的效果非常不 ...

  2. [CSDN转载]致C语言初学者—指针注意项

    在论坛里经常见到一些新人对指针提出一些问题,作为一个经历过许多错误后的新手,我想把自己的经历说出来,避免让后来人继续这样的错误.    在讲解指针之前,需要理解一下内存空间.内存是随机存取器,计算机上 ...

  3. word 多级列表设置

    今天写论文碰到了这个问题, 希望能出现这样的效果: 第一章 1.1 1.2 第二章 2.1 2.2 ...... 为了达到这个效果,晕死了.因为我的标题不是普通的默认标题一标题二   比如同济一标题 ...

  4. centos 6.5 中设置mysql 5.1.73 主从同步配置过程

    本文章给大家介绍centos 6.5设置mysql主从同步过程记录,希望文章对各位会带来帮助.  涉及到的centos系统均为虚拟机,VM下安装的版本. 在centos 6.5上设置了mysql主从功 ...

  5. 淘宝UWP桌面版公测-谁需要邀请码?

    今天taobaoUWP桌面版上线beta测试了.哪位朋友需要邀请码的,请与我联系. 前提是,您的PC已经升级到Windows 10 10586版本了,否则无法使用. 邀请码数量有限,一人一枚,共20枚 ...

  6. MySQL2:四种MySQL存储引擎

    前言 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以 ...

  7. 作业2.3 Github注册过程

    过程: 1.百度搜索Github,并且进入官网.2.打开发现是全英文网页,网页右上角找到sgin up,单击进入. 3.输入用户名.邮箱.密码,完成后单击下面绿色图标. 4.之后发现进入选择价格界面, ...

  8. 渣渣小本求职复习之路每天一博客系列——TCP/IP协议栈(5)

    前情回顾:一篇短短的博客明显不能满足TCP和UDP这两个饥渴的汉子,而且还被应用协议占了一小半的篇幅.在昨天结束之后,相信大家都基本对TCP/IP协议栈的轮廓有一个大概的印象了,能够对整体有所把握. ...

  9. Ubuntu环境搭建系列—Chrome/JDK/Android篇

    其实每次重装Ubuntu系统的时候都要进行一次基本到环境配置,而且每次总会忘记一些环境配置到东西,所以就写下这个博文,方便自己以后重装系统的时候回顾,同时也给大家做为重装系统后基本环境搭建的参考. 因 ...

  10. 使用IPostBackEventHandler让JavaScript“调用”回传事件

    在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——实践篇(二)通过自己模拟HTML标签事件与服务器交互,讲了ASP.NET的服务器控件是怎么render成HTML后市怎么“调用”后台方法 ...