Nutch 分布式运行模式 (v1.14)

Nutch 1.x 是成熟的产品级 web 爬虫,这个分支通过精细的优化配制,充分利用了具有非常强大的批处理能力的Apache Hadoop数据结构。目前该分支最新版本是 2017 年12月23日发布的 Nutch 1.14,基于 Hadoop 2.7.4 版本开发。

Nutch 的另一开发分支为 Nutch 2.x,利用 Apache Gora 作为数据中间层来处理对象的持久化映射。这样用户可以实现非常灵活数据模型来存储任何数据到各种类型的 NoSQL 存储方案中。目前该分支的最新版本是 2016 年1月21日发布的 Nutch 2.3.1。新版本 Nutch 2.4 正在开发中。

本文使用 Nutch 1.14 版,不涉及 Nutch 2.x 分支的内容。


Nutch 1.x 可以在单独的机器上运行,但要获得其强大的高可扩展性和高可伸缩性分布式处理能力还是要将其运行在 Hadoop 集群上。这是本文要阐述的内容。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    Nutch 相关概念及本机运行模式可参考另一篇文章 《走进 Apache Nutch (v1.14)》
    

1. 系统要求 (Requirements):
-------------------------------------------------------------------------------------------------------------------------
    ● Linux/Unix 环境,或 windows Cygwin 环境
    ● JDK 1.8/Java 8
    ● Apache Ant (只有从源代码构建时需要)
    
    
2. Nutch 数据库
-------------------------------------------------------------------------------------------------------------------------
nutch 数据库由下列部分组成:

① crawl 数据库,或称为 crawldb    :包含 nutch 所了解的每一个 URL 的信息,包括其是否被抓取,以及如果抓取过了,抓取的时间等相关信息。
    
② link  数据库, 或称为 linkdb    : 这个数据库包含所有已知的链接 URL,包括源 URL(source URL) 和链接文本。

③ 一系列的段数据(A set of segments): 每一个段数据是一组 URL, 作为一个抓取单元。每个段(segment)是一个目录,其中包含如下
    子目录:

    ● crawl_generate    :包含一组要抓取的 URL,文件类型为 SequenceFile
    ● crawl_fetch        :包含正在抓取的每一个 URL 的状态信息,文件类型为 MapFile
    ● content            :包含从每一个 URL 获取到的原始内容(raw content),文件类型为 MapFile
    ● parse_text        : 包含每一个 URL 解析后的文本,文件类型为 MapFile
    ● parse_data        :包含从每一个 URL 中解析出来的所有外链接(outlinks)和元数据信息,文件类型为 MapFile
    ● crawl_parse        : 包含外链接(outlink) URL, 用于更新 crawldb,文件类型为 SequenceFile
    

    
3. 准备 Hadoop 2.7.4 伪分布式 (Pseudo-Distributed Mode) 运行环境
-------------------------------------------------------------------------------------------------------------------------
Nutch 1.14 基于 Hadoop 2.7.4 版本开发,因此,首先下载 Hadoop 2.7.4 版本建立伪分布式运行环境,以确保其兼容性。


    
3.1 安装 Hadoop
-------------------------------------------------------------------------------------------------------------------------
访问 hadoop 发布包下载页面:
    
    https://archive.apache.org/dist/hadoop/common/
    
找到并下载 Hadoop 2.7.4 二进制发布包:

    [devalone@online hadoop]$ wget https://archive.apache.org/dist/hadoop/common/hadoop-2.7.4/hadoop-2.7.4.tar.gz
    
    
    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    对于 Hadoop 2.7.x 分支的最新版本,可以从 Hadoop Releases 页面访问:
    
        http://hadoop.apache.org/releases.html
    
    并从镜像站点下载到,例如清华镜像:
    
        [devalone@nutch ~]$ wget http://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz
    
    但对于历史版本,则需要访问 hadoop 存档目录:
    
        https://archive.apache.org/dist/hadoop/common/

 

解压下载包:
    [devalone@nutch ~]$ tar -zxvf hadoop-2.7.4.tar.gz


建立安装目录,将解压后的 hadoop-2.7.4 文件夹移动到新建的安装目录下:
    [devalone@nutch ~]$ sudo mkdir /opt/hadoop
    [devalone@nutch ~]$ sudo mv hadoop-2.7.4 /opt/hadoop/

进入安装目录,建立 hadoop 符号链接,便于使用和版本管理:

    [devalone@nutch ~]$ cd /opt/hadoop/
    [devalone@nutch hadoop]$ sudo ln -s hadoop-2.7.4 hadoop
    [devalone@nutch hadoop]$ ll
    总用量 0
    lrwxrwxrwx 1 root     root      12 7月  25 12:06 hadoop -> hadoop-2.7.4
    drwxr-xr-x 9 devalone devalone 149 4月  18 09:39 hadoop-2.7.4

    [devalone@nutch hadoop]$ cd hadoop
    [devalone@nutch hadoop]$ ll
    总用量 112
    drwxr-xr-x 2 devalone devalone   194 4月  18 09:39 bin
    drwxr-xr-x 3 devalone devalone    20 4月  18 09:39 etc
    drwxr-xr-x 2 devalone devalone   106 4月  18 09:39 include
    drwxr-xr-x 3 devalone devalone    20 4月  18 09:39 lib
    drwxr-xr-x 2 devalone devalone   239 4月  18 09:39 libexec
    -rw-r--r-- 1 devalone devalone 86424 4月  18 09:39 LICENSE.txt
    -rw-r--r-- 1 devalone devalone 14978 4月  18 09:39 NOTICE.txt
    -rw-r--r-- 1 devalone devalone  1366 4月  18 09:39 README.txt
    drwxr-xr-x 2 devalone devalone  4096 4月  18 09:39 sbin
    drwxr-xr-x 4 devalone devalone    31 4月  18 09:39 share
    [devalone@nutch hadoop]$ pwd
    /opt/hadoop/hadoop

编辑 /etc/profile 配置环境变量,创建 HADOOP_HOME 环境变量指向 hadoop 安装目录,将 hadoop 的 bin 和 sbin 目录添加到 PATH
环境变量中:
    [devalone@nutch hadoop]$ sudo vi /etc/profile

    HADOOP_HOME=/opt/hadoop/hadoop
    PATH=$HADOOP_HOME/bin:$PATH
    PATH=$HADOOP_HOME/sbin:$PATH

    export PATH JAVA_HOME ANT_HOME NUTCH_HOME SOLR_INSTALL HADOOP_HOME

保存退出,执行:
    [devalone@nutch hadoop]$ . /etc/profile
    [devalone@nutch hadoop]$ echo $HADOOP_HOME
    /opt/hadoop/hadoop

使其立即生效。执行:
    [devalone@nutch hadoop]$ hadoop
    Usage: hadoop [--config confdir] [COMMAND | CLASSNAME]
      CLASSNAME            run the class named CLASSNAME
     or
      where COMMAND is one of:
      fs                   run a generic filesystem user client
      version              print the version
      jar             run a jar file
                           note: please use "yarn jar" to launch
                                 YARN applications, not this command.
      checknative [-a|-h]  check native hadoop and compression libraries availability
      distcp copy file or directories recursively
      archive -archiveName NAME -p * create a hadoop archive
      classpath            prints the class path needed to get the
      credential           interact with credential providers
                           Hadoop jar and the required libraries
      daemonlog            get/set the log level for each daemon
      trace                view and modify Hadoop tracing settings

    Most commands print help when invoked w/o parameters.

执行:
    [devalone@nutch hadoop]$ hadoop version
    Hadoop 2.7.4
    Subversion https://[email protected]/repos/asf/hadoop.git -r cd915e1e8d9d0131462a0b7301586c175728a282
    Compiled by kshvachk on 2017-08-01T00:29Z
    Compiled with protoc 2.5.0
    From source with checksum 50b0468318b4ce9bd24dc467b7ce1148
    This command was run using /opt/hadoop/hadoop-2.7.4/share/hadoop/common/hadoop-common-2.7.4.jar

安装完成。


3.2 配置 Hadoop 伪分布式运行环境
-------------------------------------------------------------------------------------------------------------------------
Hadoop 可以运行为一个节点的伪分布式模式,在这种模式下,每一个 Hadoop 守护进程(daemon) 都运行在一个单独的 Java 进程中。

 

■ 配置 JAVA_HOME 环境变量:
-------------------------------------------------------------------------------------------------------------------------
Hadoop 有自己的环境配置文件 etc/hadoop/hadoop-env.sh。编辑环境配置 etc/hadoop/hadoop-env.sh 文件,在文件开始部分设置:

    JAVA_HOME=/usr/java/default

保存后退出。


■ 配置 etc/hadoop/core-site.xml:
-------------------------------------------------------------------------------------------------------------------------

   
        fs.defaultFS
        hdfs://localhost:9000
   


■ 配置 etc/hadoop/hdfs-site.xml:
-------------------------------------------------------------------------------------------------------------------------

   
        dfs.replication
        1
   


■ 配置本机登录 ssh:
-------------------------------------------------------------------------------------------------------------------------
执行:
    [devalone@nutch hadoop]$ ssh localhost

如果要求 ssh 登录密码,需要执行下列指令来配置 ssh 无密码登录:

    [devalone@nutch hadoop]$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
    [devalone@nutch hadoop]$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

确保 的文件访问权限为 600:
    [devalone@nutch hadoop]$ chmod 0600 ~/.ssh/authorized_keys

验证:
    [devalone@nutch hadoop]$ ssh localhost
    Last login: Wed Jul 25 12:30:19 2018 from localhost

OK. 无需密码可本机登录。


■ 格式化并启动 hdfs
-------------------------------------------------------------------------------------------------------------------------
① 格式化文件系统:

    [devalone@nutch hadoop]$ hdfs namenode -format
    18/07/25 12:43:50 INFO namenode.NameNode: STARTUP_MSG:
    /************************************************************
    STARTUP_MSG: Starting NameNode
    STARTUP_MSG:   host = localhost/127.0.0.1
    STARTUP_MSG:   args = [-format]
    STARTUP_MSG:   version = 2.7.4
    ...

② 启动  NameNode 和 DataNode 守护进程:

    [devalone@nutch hadoop]$ start-dfs.sh
    Starting namenodes on [localhost]
    localhost: starting namenode, logging to /opt/hadoop/hadoop-2.7.4/logs/hadoop-devalone-namenode-nutch.sansovo.org.out
    localhost: starting datanode, logging to /opt/hadoop/hadoop-2.7.4/logs/hadoop-devalone-datanode-nutch.sansovo.org.out
    Starting secondary namenodes [0.0.0.0]
    0.0.0.0: starting secondarynamenode, logging to /opt/hadoop/hadoop-2.7.4/logs/hadoop-devalone-secondarynamenode-\
    nutch.sansovo.org.out


③ 浏览 Hadoop NameNode 的 web UI,默认为:

    http://localhost:50070/

    或通过域名访问:
    http://nutch.sansovo.org:50070/
    

④ 创建 HDFS 用户目录:

    [devalone@nutch hadoop]$ hdfs dfs -mkdir /user
    [devalone@nutch hadoop]$ hdfs dfs -mkdir /user/devalone

    
⑤ 测试向 hadoop 中存储数据:

    [devalone@nutch hadoop]$ hdfs dfs -put etc/hadoop input


成功执行。


■ 在单一节点上配置 YARN
-------------------------------------------------------------------------------------------------------------------------
可以在伪分布式模式的 YARN 上运行 MapReduce 作业,需要设置几个参数并运行 ResourceManager 和 NodeManager 守护进程:

① 配置 etc/hadoop/mapred-site.xml:
    
    初始安装 Hadoop 之后,etc/hadoop/mapred-site.xml 文件并不存在,但有一个 etc/hadoop/mapred-site.xml.template 模板文件。
    复制该模板文件为 etc/hadoop/mapred-site.xml,然后在其中配置如下属性:
    
    [devalone@nutch hadoop]$ cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
    [devalone@nutch hadoop]$ vi etc/hadoop/mapred-site.xml
    
    
        
            mapreduce.framework.name
            yarn
        

    


② 配置 etc/hadoop/yarn-site.xml:

    [devalone@nutch hadoop]$ vi etc/hadoop/yarn-site.xml
    
        
            yarn.nodemanager.aux-services
            mapreduce_shuffle
        

    

③ 启动  ResourceManager 和 NodeManager 守护进程:

[devalone@nutch hadoop]$ start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /opt/hadoop/hadoop-2.7.4/logs/yarn-devalone-resourcemanager-nutch.sansovo.org.out
localhost: starting nodemanager, logging to /opt/hadoop/hadoop-2.7.4/logs/yarn-devalone-nodemanager-nutch.sansovo.org.out


④ 访问 ResourceManager 的 web UI, 默认为:

    ResourceManager - http://localhost:8088/

或通过域名访问:
    http://nutch.sansovo.org:8088/

    
现在可以通过 YARN 运行 MapReduce 作业了。


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    启动 Hadoop 集群按下列顺序执行脚本:
    
        sbin/start-dfs.sh
        sbin/start-yarn.sh
        
    停止 Hadoop 集群按下列顺序执行脚本:
    
        sbin/stop-yarn.sh
        sbin/stop-dfs.sh
        
    启动 ———— 停止,执行脚本的顺序是相反的。
    
    快捷命令:
    sbin/star-all.sh
    sbin/stop-all.sh


    
4. Nutch 1.14 分布式安装
-------------------------------------------------------------------------------------------------------------------------
Nutch 分布式部署以 MapReduce job 方式运行,除脚本之外,整个运行类库和资源文件打包为一个 apache-nutch-1.x.job 文件,而且每次修改配置文件之后,都需要重新打包 .job 文件,使其生效,因此需要 Nutch 源码包进行编译。


4.1 构建 Nutch 编译环境
-------------------------------------------------------------------------------------------------------------------------
源码安装 Nutch 需要 ant 配合 ivy 依赖类库构建编译环境,过程如下:

    [devalone@online apache]$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//ant/binaries/apache-ant-1.10.5-bin.tar.gz
    [devalone@online apache]$ wget http://mirrors.hust.edu.cn/apache//ant/ivy/2.5.0-rc1/apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@online apache]$ ll
    总用量 8352
    -rw-rw-r--. 1 devalone devalone 5829814 7月  13 18:10 apache-ant-1.10.5-bin.tar.gz
    -rw-rw-r--. 1 devalone devalone 2716983 4月  12 23:46 apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@nutch apache]$ tar -zxvf apache-ant-1.10.5-bin.tar.gz
    [devalone@nutch apache]$ tar -zxvf apache-ivy-2.5.0-rc1-bin.tar.gz

    [devalone@nutch apache]$ sudo mv apache-ant-1.10.5-bin.tar.gz /usr/local/lib/apache/ant/
    [devalone@nutch apache]$ cd /usr/local/lib/apache/ant/
    [devalone@nutch ant]$ sudo ln -s apache-ant-1.10.5 ant

    [devalone@nutch ant]$ pwd
    /usr/local/lib/apache/ant/ant

将 ivy 的 jar 包复制到 ant 的 lib/ 目录下:

    [devalone@nutch apache-ivy-2.5.0-rc1]$ cp ivy-2.5.0-rc1.jar /usr/local/lib/apache/ant/ant/lib/
    
    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    实际上 nutch 源码包 ivy/ 目录下自带了 ivy-2.4.0.jar 文件,也可以直接使用这个 jar 包文件,而不必自己单独下载 ivy 的 jar
    文件。
    

编辑 /etc/profile 文件,设置 ANT_HOME 环境变量,并将 ant/bin 添加到 PATH 中:

    JAVA_HOME=/usr/java/default
    PATH=$JAVA_HOME/bin:$PATH

    ANT_HOME=/usr/local/lib/apache/ant/ant
    PATH=$ANT_HOME/bin:$PATH

    export PATH JAVA_HOME ANT_HOME
        
保存退出,执行:

    [devalone@nutch ant]$ source /etc/profile

    使其立即生效。

    [devalone@nutch ant]$ ant -version
    Apache Ant(TM) version 1.10.5 compiled on July 10 2018
    
编译环境安装完成。


4.2 执行 Nutch 源码编译
-------------------------------------------------------------------------------------------------------------------------


4.2.1 下载并解压 Nutch 源码包
-------------------------------------------------------------------------------------------------------------------------
● 使用清华镜像站点下载:

    [devalone@nutch ~]$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/nutch/1.14/apache-nutch-1.14-src.tar.gz

● 解压源码包:

    [devalone@nutch ~]$ tar -zxvf apache-nutch-1.14-src.tar.gz

    [devalone@nutch ~]$ ll
    总用量 5268
    drwxrwxr-x 3 devalone devalone     109 7月  20 10:12 apache
    drwxrwxr-x 7 devalone devalone     162 7月  20 10:36 apache-nutch-1.14
    -rw-rw-r-- 1 devalone devalone 5390394 7月  20 10:36 apache-nutch-1.14-src.tar.gz

    
4.2.2 配置 ivy/ivysettings.xml
-------------------------------------------------------------------------------------------------------------------------    
由于 nutch 源码使用国外 maven 仓库作为 ivy 依赖仓库,国内下载通常非常慢,可以使用国内的镜像仓库替换掉这些仓库。共有 3 个可配置的仓库:

       value="http://oss.sonatype.org/content/repositories/releases/"
    override="false"/>
      value="http://repo1.maven.org/maven2/"
    override="false"/>
      value="https://repository.apache.org/content/repositories/snapshots/"
    override="false"/>    

将这 3 个仓库替换为国内的镜像仓库,示例:

    http://maven.aliyun.com/nexus/content/groups/public/
    http://maven.aliyun.com/nexus/content/repositories/central/
    http://maven.aliyun.com/nexus/content/repositories/apache-snapshots/
    
本例使用本地网络环境内配置好的 maven 仓库:

       value="http://repo.sansovo.org:8081/nexus/content/groups/public/"
    override="false"/>
      value="http://repo.sansovo.org:8081/nexus/content/groups/public/"
    override="false"/>
      value="http://repo.sansovo.org:8081/nexus/content/groups/public-snapshot/"
    override="false"/>


4.2.3 sonar-ant-task-2.2.jar
-------------------------------------------------------------------------------------------------------------------------
编译 nutch 依赖 sonar-ant-task-2.2.jar 任务包,但 ivy 无法加载该包的资源定义 org/sonar/ant/antlib.xml,需要手动下载,
否则出现如下错误:
    [taskdef] Could not load definitions from resource org/sonar/ant/antlib.xml. It could not be found.
    ivy-download:
    [taskdef] Could not load definitions from resource org/sonar/ant/antlib.xml. It could not be found.

下载地址:
    https://download.csdn.net/download/devalone/10554266

将下载解压的 sonar-ant-task-2.2.jar 包文件复制到 ant/lib/ 目录下:
    [devalone@nutch ant]$ sudo cp ~/sonar-ant-task-2.2.jar ant/lib/

 

4.2.4 配置 Nutch
-------------------------------------------------------------------------------------------------------------------------
由于 Nutch 将所有类库和资源文件,包括配置文件打包为一个 .job 文件,因此,应该在执行源码编译之前修改配置信息。当然也可以使用 jar 工具的 -u 选项更新某个配置文件。这里使用先配置后编译的方法,一次性完成整改 .job 文件的更新方法。

● Nutch 要求在运行前至少要配置 http.agent.name 属性。因此打开 conf/nutch-site.xml 文件,配置类似如下的内容:

进入解压后的源码目录: apache-nutch-1.14

    [devalone@nutch ~]$ cd apache-nutch-1.14
    [devalone@nutch apache-nutch-1.14]$ ll
    总用量 504
    -rw-rw-r-- 1 devalone devalone  54529 12月 19 2017 build.xml
    -rw-rw-r-- 1 devalone devalone 106848 12月 19 2017 CHANGES.txt
    drwxr-xr-x 2 devalone devalone   4096 7月  20 10:36 conf
    -rw-rw-r-- 1 devalone devalone   6297 12月 19 2017 default.properties
    drwxr-xr-x 3 devalone devalone     17 12月 19 2017 docs
    drwxr-xr-x 2 devalone devalone    148 7月  20 10:36 ivy
    drwxr-xr-x 3 devalone devalone     20 12月 19 2017 lib
    -rw-rw-r-- 1 devalone devalone 329066 12月 19 2017 LICENSE.txt
    -rw-rw-r-- 1 devalone devalone    427 12月 19 2017 NOTICE.txt
    drwxr-xr-x 7 devalone devalone     76 12月 19 2017 src
    

    [devalone@nutch nutch]$ vi conf/nutch-site.xml
    
        http.agent.name
        My Nutch Spider
    

    该属性值随便设置一个合理的字符串,只要不是空串或空白串就好。

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    http.agent.name 属性的配置其实是有些讲究的。有些站点会配置 robots 协议或者其他机制禁止网络爬虫的爬取。针对 robots 协议,可以将 http.agent.name 设置为正常浏览器 User-Agent 请求头属性值。获取方法很多,这里不赘述。示例:

    
      http.agent.name
      Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
      HTTP 'User-Agent' request header. MUST NOT be empty -
      please set this to a single word uniquely related to your organization.

      NOTE: You should also check other related properties:

        http.robots.agents
        http.agent.description
        http.agent.url
        http.agent.email
        http.agent.version

      and set their values appropriately.

     
    
    
    或者 Linux 上的:
    
        Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

    可通过百度资源平台 https://ziyuan.baidu.com/robots 对网站的 robots 配置进行检测分析,了解某个网站的 robots 配置情况。
        

● 另外要确认 plugin.includes 属性中包含所索引器插件 indexer-solr,用于之后建立 solr 索引。该属性在默认配置文件
conf/nutch-default.xml 中设置为:

    
      plugin.includes
      protocol-http|urlfilter-(regex|validator)|parse-(html|tika)|index-(basic|anchor)|indexer-solr|scoring-opic|\
      urlnormalizer-(pass|regex|basic)

      Regular expression naming plugin directory names to
      include.  Any plugin not matching this expression is excluded.
      In any case you need at least include the nutch-extensionpoints plugin. By
      default Nutch includes crawling just HTML and plain text via HTTP,
      and basic indexing and search plugins. In order to use HTTPS please enable
      protocol-httpclient, but be aware of possible intermittent problems with the
      underlying commons-httpclient library. Set parsefilter-naivebayes for classification based focused crawler.
     

    

可以看出,indexer-solr 插件已经包含到系统配置中,因此,保持默认配置就好。

 

4.2.5 执行 Nutch 编译
-------------------------------------------------------------------------------------------------------------------------
确保在源码根目录下:

    [devalone@nutch apache-nutch-1.14]$ ll
    总用量 508
    drwxrwxr-x 76 devalone devalone   4096 7月  21 15:15 build
    -rw-rw-r--  1 devalone devalone  54529 12月 19 2017 build.xml
    -rw-rw-r--  1 devalone devalone 106848 12月 19 2017 CHANGES.txt
    drwxr-xr-x  2 devalone devalone   4096 7月  25 16:52 conf
    -rw-rw-r--  1 devalone devalone   6297 12月 19 2017 default.properties
    drwxr-xr-x  3 devalone devalone     17 12月 19 2017 docs
    drwxr-xr-x  2 devalone devalone    148 7月  21 11:08 ivy
    drwxr-xr-x  3 devalone devalone     20 12月 19 2017 lib
    -rw-rw-r--  1 devalone devalone 329066 12月 19 2017 LICENSE.txt
    -rw-rw-r--  1 devalone devalone    427 12月 19 2017 NOTICE.txt
    drwxrwxr-x  4 devalone devalone     33 7月  21 13:43 runtime
    drwxrwxr-x  4 devalone devalone     33 7月  21 11:36 runtime.old
    drwxr-xr-x  7 devalone devalone     76 12月 19 2017 src

运行 ant 命令:

    [devalone@nutch apache-nutch-1.14]$ ant
    Buildfile: /home/devalone/apache-nutch-1.14/build.xml
    Trying to override old definition of task javac

    ivy-probe-antlib:

    ivy-download:

    ivy-download-unchecked:

    ivy-init-antlib:

    ivy-init:

    init:

    clean-default-lib:

    resolve-default:
    [ivy:resolve] :: Apache Ivy 2.5.0-rc1 - 20180412005306 :: http://ant.apache.org/ivy/ ::
    [ivy:resolve] :: loading settings :: file = /home/devalone/apache-nutch-1.14/ivy/ivysettings.xml
    [ivy:resolve] downloading http://repo.sansovo.org:8081/nexus/content/groups/public/org/apache/commons
    /commons-compress/1.14/commons-compress-1.14.jar ...
    [ivy:resolve] ........................................................................................
    ......................................... (517kB)
    [ivy:resolve] .. (0kB)
    [ivy:resolve]   [SUCCESSFUL ] org.apache.commons#commons-compress;1.14!commons-compress.jar (6470ms)
    [ivy:resolve] downloading http://repo.sansovo.org:8081/nexus/content/groups/public/org/apache/hadoop/
    hadoop-common/2.7.4/hadoop-common-2.7.4.jar ...
    [ivy:resolve] ........................................................................................
    ..............................................
    
    ....
    

    BUILD SUCCESSFUL
    Total time: 18 minutes 5 seconds

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    第一次构建过程中最好不要中断,以免 ivy 依赖库文件下载损坏,使编译发生一些奇怪的错误。如果确实出现错误,可以清除掉    ~/.ivy2/cache/ 目录重新构建。

    之后如果再次构建,~/.ivy2 库已完整下载,构建会很快完成,如:
    
    ...
    BUILD SUCCESSFUL
    Total time: 35 seconds


编译完成后,在源码目录下生成 runtime 目录,该目录下即是构建出的二进制可执行文件包:

    [devalone@nutch apache-nutch-1.14]$ ll runtime/
    总用量 0
    drwxrwxr-x 3 devalone devalone 46 7月  21 11:36 deploy
    drwxrwxr-x 7 devalone devalone 67 7月  21 11:37 local

其中 deploy 目录为分布式可执行文件包,local 目录为本地模式可执行文件包。

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    执行 ant clean 指令会清除 runtime 目录,注意备份配置文件。


查看 runtime/deploy/ 目录:

    [devalone@nutch apache-nutch-1.14]$ ll runtime/deploy/
    总用量 233172
    -rw-rw-r-- 1 devalone devalone 238767840 7月  21 13:43 apache-nutch-1.14.job
    drwxrwxr-x 2 devalone devalone        32 7月  21 13:43 bin
    
    [devalone@nutch apache-nutch-1.14]$ ll runtime/deploy/bin/
    总用量 24
    -rwxrwxr-x 1 devalone devalone  9301 7月  21 13:43 crawl
    -rwxrwxr-x 1 devalone devalone 12020 7月  21 13:43 nutch

分布式模式的 nutch 只有一个 apache-nutch-1.14.job 文件和两个脚本文件:crawl 和 nutch。

 


5. 配置 URL 种子列表(URL seed list)
-------------------------------------------------------------------------------------------------------------------------
    ● URL 种子列表包含 nutch 要搜索的 web 站点 URL 列表,一行一个 URL。
    ● conf/regex-urlfilter.txt 过滤器文件使用正则表达式来过滤和限定允许 nutch 爬取和下载的的资源类型。


5.1 创建 URL 种子列表
-------------------------------------------------------------------------------------------------------------------------
创建一个特定的目录用于存储 URL 列表文件,在该目录下创建一个或多个文本文件,每个文本文件就是一个种子列表文件。编辑文件,向
其中添加要爬取的 web 站点 URL 地址,一行一个 URL。

示例:
    [devalone@nutch apache-nutch-1.14]$ cd runtime/deploy/
    [devalone@nutch apache-nutch-1.14]$ mkdir -p urls
    [devalone@nutch apache-nutch-1.14]$ cd urls

    [devalone@nutch urls]$ vi seed.txt
    [devalone@nutch urls]$ cat seed.txt
    http://news.sohu.com/
    http://mil.sohu.com/
    https://blog.csdn.net/

 


5.2 配置正则表达式过滤器(可选)
-------------------------------------------------------------------------------------------------------------------------
正则表达式过滤器由 conf/regex-urlfilter.txt 文件配置,用于限定 nutch 爬取的资源在可控的范围内。如果失去控制,nutch 很可能爬取整个互联网的 web 资源,恐怕会耗费几周的时间。

其中任何一个非注释的,非空白的行包含一个正则表达式。

正则表达式以 + 或 - 开始:

    ● + 符号:    表示允许 nutch 爬取的资源。
    ● - 符号:    表示禁止 nutch 爬取的资源。

一个 URL 在此文件中的第一个匹配模式确定了其是包含到爬取列表还是被忽略掉。如果在此文件中没有任何模式匹配,则该 URL 被忽略。

本例限定 nutch 在种子列表中列出的网址范围内爬取,其它网站忽略,因此编辑 conf/regex-urlfilter.txt 文件,注释掉如下的正则表达式:

    # accept anything else
    # +.

添加如下正则表达式:

    +^https?://(news|mil)\.sohu\.com/
    +^https?://blog\.csdn\.net/


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    如果没有在 regex-urlfilter.txt 文件中指定域名,会导致在种子 URL 页面中链接的所有 URL 都会被爬取,数量不可控。
    


5.3 重新构建
-------------------------------------------------------------------------------------------------------------------------
由于改变了 conf/regex-urlfilter.txt 文件的配置,因此需要再次运行 ant 命令重新构建:

    [devalone@nutch apache-nutch-1.14]$ ant
    Buildfile: /home/devalone/apache-nutch-1.14/build.xml
    Trying to override old definition of task javac

    ivy-probe-antlib:

    ivy-download:

    ivy-download-unchecked:
    ...
    
    BUILD SUCCESSFUL
    Total time: 12 seconds

再次构建由于不需要下载 ivy 依赖文件,因此,很快完成。

 

6. 在伪分布式模式 Hadoop 集群上执行 Nutch 作业
-------------------------------------------------------------------------------------------------------------------------

 

6.1 启动 Solr
-------------------------------------------------------------------------------------------------------------------------
为了在 nutch 爬取过程中直接建立 solr 索引,因此需要启动一个 本机运行的 solr 服务。

    
    ● NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    本机安装和运行 Solr 安装参考 《走进 Apache Nutch (v1.14)》。
    

① 为创建新的 phadoop core 准备资源:

    [devalone@nutch solr]$ cd $SOLR_INSTALL/server/solr/configsets/
    [devalone@nutch configsets]$ cp -r nutch phadoop

② 启动 solr:

    [devalone@nutch configsets]$ solr start
    NOTE: Please install lsof as this script needs it to determine if Solr is listening on port 8983.

    Started Solr server on port 8983 (pid=21469). Happy searching!

③ 创建 phadoop core

    [devalone@nutch solr]$ solr create -c phadoop -d server/solr/configsets/phadoop/conf/

    Copying configuration to new core instance directory:
    /opt/solr/solr/server/solr/phadoop

    Creating new core 'phadoop' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=phadoop&instanceDir=phadoop

    {
      "responseHeader":{
        "status":0,
        "QTime":335},
      "core":"phadoop"}
 
④ 将新创建的 core name 添加到 Solr server URL:

    -Dsolr.server.url=http://localhost:8983/solr/phadoop
    
    或:
    -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/phadoop/

 

6.2 将 URL 种子文件目录存储到伪分布式模式 Hadoop 集群上
-------------------------------------------------------------------------------------------------------------------------

    [devalone@nutch apache-nutch-1.14]$ cd runtime/deploy/
    [devalone@nutch deploy]$ hdfs dfs -put urls urls

    [devalone@nutch deploy]$ hdfs dfs -ls
    Found 2 items
    drwxr-xr-x   - devalone supergroup          0 2018-07-25 17:18 input
    drwxr-xr-x   - devalone supergroup          0 2018-07-25 17:27 urls


6.3 在伪分布式模式 Hadoop 集群上执行 Nutch 爬取作业
-------------------------------------------------------------------------------------------------------------------------
确认当前工作目录为 nutch 分布式模式目录:

    [devalone@nutch deploy]$ pwd
    /home/devalone/apache-nutch-1.14/runtime/deploy
    [devalone@nutch deploy]$ ll
    总用量 233172
    -rw-rw-r-- 1 devalone devalone 238768128 7月  25 16:59 apache-nutch-1.14.job
    drwxrwxr-x 2 devalone devalone        32 7月  21 13:43 bin
    drwxrwxr-x 2 devalone devalone        22 7月  25 17:10 urls


● 执行爬取任务:

    [devalone@online deploy]$ bin/crawl -i -D solr.server.url=http://nutch.sansovo.org:8983/solr/phadoop/ -s urls phadoop 3
    Injecting seed URLs
    /home/devalone/apache-nutch-1.14/runtime/deploy/bin/nutch inject phadoop/crawldb urls
    18/07/28 10:56:09 INFO crawl.Injector: Injector: starting at 2018-07-28 10:56:09
    18/07/28 10:56:09 INFO crawl.Injector: Injector: crawlDb: phadoop/crawldb
    18/07/28 10:56:09 INFO crawl.Injector: Injector: urlDir: urls
    18/07/28 10:56:09 INFO crawl.Injector: Injector: Converting injected urls to crawl db entries.
    18/07/28 10:56:10 INFO client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032
    18/07/28 10:56:11 INFO input.FileInputFormat: Total input paths to process : 1
    18/07/28 10:56:11 INFO input.FileInputFormat: Total input paths to process : 0
    18/07/28 10:56:11 INFO mapreduce.JobSubmitter: number of splits:1
    18/07/28 10:56:11 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1532745058248_0001
    18/07/28 10:56:12 INFO impl.YarnClientImpl: Submitted application application_1532745058248_0001
    18/07/28 10:56:12 INFO mapreduce.Job: The url to track the job: http://localhost:8088/proxy/application_1532745058248_0001/
    18/07/28 10:56:12 INFO mapreduce.Job: Running job: job_1532745058248_0001
    18/07/28 10:56:24 INFO mapreduce.Job: Job job_1532745058248_0001 running in uber mode : false
    18/07/28 10:56:24 INFO mapreduce.Job:  map 0% reduce 0%
    18/07/28 10:56:29 INFO mapreduce.Job:  map 100% reduce 0%
    18/07/28 10:56:35 INFO mapreduce.Job:  map 100% reduce 100%
    18/07/28 10:56:36 INFO mapreduce.Job: Job job_1532745058248_0001 completed successfully
    18/07/28 10:56:36 INFO mapreduce.Job: Counters: 50

    ...
    
    18/07/28 13:04:40 INFO indexer.CleaningJob: CleaningJob: finished at 2018-07-28 13:04:40, elapsed: 00:00:24
    2018年 07月 28日 星期六 13:04:40 CST : Finished loop with 3 iterations
    
共计使用 2:8:31 的时间。
    

从输出可以看出执行的 mapreduce 作业。通过浏览器访问:http://nutch.sansovo.org:8088/cluster/apps,可以看到几个正在运行的作业。

在爬取过程中查看 hadoop 目录:

    [devalone@nutch deploy]$ hadoop fs -ls
    Found 2 items
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 10:59 phadoop
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 10:55 urls

    [devalone@nutch deploy]$  hadoop fs -ls phadoop
    Found 3 items
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 13:03 phadoop/crawldb
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 13:02 phadoop/linkdb
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 11:15 phadoop/segments


    [devalone@nutch deploy]$ hdfs dfs -ls phadoop/segments
    Found 2 items
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 10:58 phadoop/segments/20180728105708
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 11:10 phadoop/segments/20180728110207

 
作业会在 hadoop 目录 phadoop 下创建 3 个 nutch 数据库目录:crawldb/linkdb/segments,分别存放三种类型的数据库文件。其中
segments 目录下已经创建了 2 个 segment,说明当前正在进行第二次迭代抓取。


运行过程中,浏览器上打开链接:

    http://nutch.sansovo.org:8983/solr/#/phadoop/query

已经可以搜索到不同迭代过程中的爬取出的结果。

最后完成时,可以搜索到 3 次迭代的爬取的最终结果。

再次查看数据库目录:
    [devalone@nutch deploy]$  hadoop fs -ls phadoop/segments
    Found 3 items
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 10:58 phadoop/segments/20180728105708
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 11:10 phadoop/segments/20180728110207
    drwxr-xr-x   - devalone supergroup          0 2018-07-28 13:00 phadoop/segments/20180728111502


可以看出,进行了全部的 3 次 爬取过程,这与执行的命令行参数设置完全一致。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------
    运行过程中可能会发生如下错误:

        Container killed on request. Exit code is 143
        Container exited with a non-zero exit code 143

        18/07/26 12:25:35 INFO mapreduce.Job: Task Id : attempt_1532577045041_0020_r_000000_1, Status : FAILED
        Container [pid=45483,containerID=container_1532577045041_0020_01_000020] is running beyond virtual memory limits.
        Current usage: 167.6 MB of 1 GB physical memory used; 2.8 GB of 2.1 GB virtual memory used. Killing container.

    问题原因: hadoop 运行时使用的虚拟内存不足, hadoop 物理内存默认与主机的内存一致,hadoop 虚拟内存默认是 hadoop 物理内存的  2.1倍。

    修改 hadoop 物理内存的大小,在 mapred-site.xml 设置:

        
            mapreduce.map.memory.mb
            2048
        

        
            mapreduce.reduce.memory.mb
            2048
        

    
    
    或者修改 hadoop 虚拟内存与 hadoop 物理内存的比率值,在 yarn-site.xml 设置:


    yarn.nodemanager.vmem-pmem-ratio
    3

    
    重启 Hadoop 即可。
    
    再次运行抓取命令时,为保证运行结果的准确性,应删除集群上 phdoop 数据库目录:
    
    [devalone@nutch hadoop]$ hdfs dfs -rm -f -r phadoop

    

*    
*    
*    

7. 在分布式 Hadoop 集群上运行 Nutch 爬取作业
-------------------------------------------------------------------------------------------------------------------------
在实际生产环境中,Nutch 应运行在真实的分布式 Hadoop 集群上,而非单机模式或伪分布模式。


这里有一个实际的小型 ambari 管理集群,运行 hadoop 7.3 版本,共 9 部机器,主机名称分别为:

    namenode.sansovo.org
    snamenode.sansovo.org
    rm.sansovo.org
    ambri.sansovo.org
    solr.sansovo.org
    worker-1.sansovo.org
    worker-2.sansovo.org
    worker-3.sansovo.org
    worker-4.sansovo.org


    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    关于如何使用 ambari 构建和管理 hadoop 集群,参考 《Ambari 2.6.1 构建 Hadoop 集群 ---- CentOS 7》。本文专注于 Nutch
    在分布式 hadoop 环境中的运行。

 

7.1 为 Hadoop 集群创建 Solr 的新 core
-------------------------------------------------------------------------------------------------------------------------
在 Solr 上创建新的 core,名称为 cluster,作为分布式集群的 Solr 索引服务。

    [devalone@nutch solr]$ cd $SOLR_INSTALL/server/solr/configsets/
    [devalone@nutch configsets]$ cp -r phadoop cluster
    [devalone@nutch solr]$ cd $SOLR_INSTALL

启动 Solr:
    [devalone@nutch solr]$ solr start
    NOTE: Please install lsof as this script needs it to determine if Solr is listening on port 8983.

    Started Solr server on port 8983 (pid=1608). Happy searching!


创建 cluster core:
    [devalone@nutch solr]$  solr create -c cluster -d server/solr/configsets/cluster/conf/

    Copying configuration to new core instance directory:
    /opt/solr/solr/server/solr/cluster

    Creating new core 'cluster' using command:
    http://localhost:8983/solr/admin/cores?action=CREATE&name=cluster&instanceDir=cluster

    {
      "responseHeader":{
        "status":0,
        "QTime":456},
      "core":"cluster"}


    OK.

将新创建的 cluster core 添加到 Solr server URL,用于建立索引的 Solr server URL:

    -Dsolr.server.url=http://localhost:8983/solr/cluster
    
    或:
    -Dsolr.server.url=http://nutch.sansovo.org:8983/solr/cluster/
    
    
    

7.2 编译 nutch 1.14, 并将 URL 种子文件目录存储到分布式模式 Hadoop 集群上
-------------------------------------------------------------------------------------------------------------------------
登录到集群主机 worker-1.sansovo.org 上,并切换到集群用户 ambari-qa, 浏览集群目录:

    [ambari-qa@worker-1 ~]$ hadoop fs -ls /
    Found 7 items
    drwxrwxrwx   - yarn   hadoop          0 2018-08-02 14:09 /app-logs
    drwxr-xr-x   - yarn   hadoop          0 2018-08-02 12:32 /ats
    drwxr-xr-x   - hdfs   hdfs            0 2018-08-02 14:09 /hdp
    drwxr-xr-x   - mapred hdfs            0 2018-08-02 14:09 /mapred
    drwxrwxrwx   - mapred hadoop          0 2018-08-02 14:19 /mr-history
    drwxrwxrwx   - hdfs   hdfs            0 2018-08-02 14:09 /tmp
    drwxr-xr-x   - hdfs   hdfs            0 2018-08-02 12:20 /user
    [ambari-qa@worker-1 ~]$ hadoop fs -ls /user
    Found 1 items
    drwxrwx---   - ambari-qa hdfs          0 2018-08-02 12:20 /user/ambari-qa
    [ambari-qa@worker-1 ~]$ hadoop fs -ls /user/ambari-qa
    [ambari-qa@worker-1 ~]$


下载编译 nutch 1.14 源码包,并进入 runtime/deploy/ 目录,将准备好的 urls 目录及种子文件 urls/seed.txt 存储到 hadoop 中:

    [ambari-qa@worker-1 apache-nutch-1.14]$ cd runtime/deploy/
    ambari-qa@worker-1 apache-nutch-1.14]$ hdfs dfs -put urls urls

    [ambari-qa@worker-1 deploy]$ hadoop fs -put urls urls
    [ambari-qa@worker-1 deploy]$ hadoop fs -ls /user/ambari-qa
    Found 1 items
    drwxr-xr-x   - ambari-qa hdfs          0 2018-08-02 15:28 /user/ambari-qa/urls
    [ambari-qa@worker-1 deploy]$ hadoop fs -ls /user/ambari-qa/urls
    Found 1 items
    -rw-r--r--   3 ambari-qa hdfs         66 2018-08-02 15:28 /user/ambari-qa/urls/seed.txt

    
    
7.3 在分布式模式 Hadoop 集群上执行 Nutch 爬取作业
-------------------------------------------------------------------------------------------------------------------------
确认当前工作目录为 nutch 分布式模式目录:

    [ambari-qa@worker-1 deploy]$ pwd
    /home/ambari-qa/apache-nutch-1.14/runtime/deploy
    [ambari-qa@worker-1 deploy]$ ll
    total 233212
    -rw-r--r-- 1 ambari-qa hadoop 238768128 Jul 25 16:59 apache-nutch-1.14.job
    drwxr-xr-x 2 ambari-qa hadoop        32 Jul 21 13:43 bin
    -rw------- 1 ambari-qa hadoop     40151 Jul 26 09:59 nohup.out
    drwxr-xr-x 2 ambari-qa hadoop        22 Jul 25 17:10 urls


● 执行爬取任务:

[ambari-qa@worker-1 deploy]$ bin/crawl -i -D solr.server.url=http://nutch.sansovo.org:8983/solr/cluster/ -s urls cluster 3
Injecting seed URLs
/home/ambari-qa/apache-nutch-1.14/runtime/deploy/bin/nutch inject cluster/crawldb urls
18/08/02 15:34:34 INFO crawl.Injector: Injector: starting at 2018-08-02 15:34:34
18/08/02 15:34:34 INFO crawl.Injector: Injector: crawlDb: cluster/crawldb
18/08/02 15:34:34 INFO crawl.Injector: Injector: urlDir: urls
18/08/02 15:34:34 INFO crawl.Injector: Injector: Converting injected urls to crawl db entries.
18/08/02 15:34:35 INFO client.RMProxy: Connecting to ResourceManager at rm.sansovo.org/192.168.0.53:8050
18/08/02 15:34:35 INFO client.AHSProxy: Connecting to Application History server at namenode.sansovo.org/192.168.0.51:10200
18/08/02 15:34:39 INFO input.FileInputFormat: Total input paths to process : 0
18/08/02 15:34:39 INFO input.FileInputFormat: Total input paths to process : 1
18/08/02 15:34:39 INFO mapreduce.JobSubmitter: number of splits:1
18/08/02 15:34:40 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1533190305228_0001
18/08/02 15:34:40 INFO impl.YarnClientImpl: Submitted application application_1533190305228_0001
18/08/02 15:34:41 INFO mapreduce.Job: The url to track the job: http://rm.sansovo.org:8088/proxy/application_1533190305228_0001/
18/08/02 15:34:41 INFO mapreduce.Job: Running job: job_1533190305228_0001
18/08/02 15:34:58 INFO mapreduce.Job: Job job_1533190305228_0001 running in uber mode : false
18/08/02 15:34:58 INFO mapreduce.Job:  map 0% reduce 0%
18/08/02 15:35:14 INFO mapreduce.Job:  map 100% reduce 0%
18/08/02 15:35:23 INFO mapreduce.Job:  map 100% reduce 100%
18/08/02 15:35:23 INFO mapreduce.Job: Job job_1533190305228_0001 completed successfully
18/08/02 15:35:23 INFO mapreduce.Job: Counters: 50


...

18/08/02 17:38:41 INFO fetcher.Fetcher: Fetcher: finished at 2018-08-02 17:38:41, elapsed: 01:41:43
Parsing : 20180802155625

...


18/08/02 17:44:24 INFO indexer.CleaningJob: CleaningJob: finished at 2018-08-02 17:44:24, elapsed: 00:00:30
Thu Aug 2 17:44:24 CST 2018 : Finished loop with 3 iterations


第三次抓取用了 01:41:43 的时间,用时较长,占用了大部分时间。

最后完成 3 次抓取,共计用时 2:9:54 的时间。


从输出可以看出执行的 mapreduce 作业。通过浏览器访问:http://rm.sansovo.org:8088/cluster/apps,可以看到正在运行的作业。    

访问 http://namenode.sansovo.org:50070/dfshealth.html#tab-datanode 查看集群存储系统变化。


通过 http://nutch.sansovo.org:8983/solr/#/cluster/query 可以搜索到抓取的结果。

 

    NOTE:
    ---------------------------------------------------------------------------------------------------------------------
    理论上,Hadoop 2.7.x 分支的各个版本都可以保持向后兼容性,因此 Nutch 1.14 应该支持该分支上的所有版本,包括当前最新版本  Hadoop 2.7.6。
    
    本人在伪分布模式下测试通过了:
        
        Hadoop 2.7.3
        Hadoop 2.7.4
        Hadoop 2.7.6
    
    Nutch 1.14 可以很好地运行在这 3 个版本 Hadoop 的伪分布式运行模式下,没有出现异常。
    
    Nutch 1.14 与目前最新版本的 Hadoop 3.1.0 并不兼容,测试时抛出 MapReduce 异常。
    
    
    
    
    
    
                    (本篇完)

 

 


-------------------------------------------------------------------------------------------------------------------------

参考:

    https://wiki.apache.org/nutch/NutchHadoopTutorial
    https://wiki.apache.org/nutch/NutchHadoopSingleNodeTutorial
    https://hadoop.apache.org/docs/r2.7.4/hadoop-project-dist/hadoop-common/SingleCluster.html

你可能感兴趣的:(Nutch)