文档章节

Nutch的HDFS文件输出

强子哥哥
 强子哥哥
发布于 2014/12/11 14:43
字数 1066
阅读 1338
收藏 23
点赞 2
评论 0

以1.7为例,之前Nutch的输出可以自定义其它存储系统中,具体原理不赘述。

项目有个需求,就是文件仍然保存在HDFS中,而不是索引到其它存储系统中。

也就是说,不用写

public class XXX implements IndexWriter

这样的插件了,

那么,问题来了,怎么修改Nutch的源码,使得结果顺利存在HDFS中呢?

----------那就让我们从源头一步一步来修改,碰到问题就解决问题。

首先Crawl.java中,原先在索引阶段有这么一些代码。

if (i > 0) {
      linkDbTool.invert(linkDb, segments, true, true, false); // invert links

      if (solrUrl != null) {
        // index, dedup & merge
        FileStatus[] fstats = fs.listStatus(segments, HadoopFSUtil.getPassDirectoriesFilter(fs));
        
        IndexingJob indexer = new IndexingJob(getConf());
        indexer.index(crawlDb, linkDb, 
                Arrays.asList(HadoopFSUtil.getPaths(fstats)));

        SolrDeleteDuplicates dedup = new SolrDeleteDuplicates();
        dedup.setConf(getConf());
        dedup.dedup(solrUrl);
      }

最关键的是

IndexingJob indexer = new IndexingJob(getConf());
        indexer.index(crawlDb, linkDb, 
                Arrays.asList(HadoopFSUtil.getPaths(fstats)));

也就是说,这里是索引的入口处。

这里把这些代码屏蔽掉,我个人的方法是 if (solrUrl != null) {------》if (false) {

这样还能保持原先的代码存在,这样如果后面的代码有问题还可以恢复此代码。

---------------接下来呢?添加我们自己的索引任务代码如下:

if (true) {
  // add my index job
  // index, dedup & merge
  FileStatus[] fstats = fs.listStatus(segments,
  HadoopFSUtil.getPassDirectoriesFilter(fs));
  IndexingJob indexer = new IndexingJob(getConf());
  indexer.index(crawlDb, linkDb,Arrays.asList(HadoopFSUtil.getPaths(fstats)), true,false, null);
}

这样,就完成了索引任务外围的改造,这里只是改了个外观,还没伤筋动骨。

下面我们开始对内部进行改造!

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

首先,我们得找到MR的方法吧,入口在哪呢?

IndexerMapReduce.initMRJob(crawlDb, linkDb, segments, job);

这句话,跟进去,就能看到具体的MR类,如下:

job.setMapperClass(IndexerMapReduce.class);
 job.setReducerClass(IndexerMapReduce.class);

也就是说,MR类都是IndexerMapReduce.class.

那么我们就开始分析这个类的map和reduce函数。

备注: 我的URL文件的格式是 url   \t   sender=xxx   \t   receiver=xxx   \t   oldname=xxx     \t   newname=xxx   \n

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

改动的几个地方如下:

1 对于reduce的函数声明

public void reduce(Text key, Iterator<NutchWritable> values,
                     OutputCollector<Text, NutchIndexAction> output, Reporter reporter)

修改为

public void reduce(Text key, Iterator<NutchWritable> values,
                     OutputCollector<Text, Text> output, Reporter reporter)

这会导致出现3个错误,把这3个地方屏蔽掉即可。

2 看reduce的最后两行

NutchIndexAction action = new NutchIndexAction(doc, NutchIndexAction.ADD);
output.collect(key, action);

这里需要做一个改动如下:

// NutchIndexAction action = new NutchIndexAction(doc,
		// NutchIndexAction.ADD);
		// output.collect(key, action);
		Object senderObject = doc.getFieldValue("sender");
		Object receiverObject = doc.getFieldValue("receiver");
		Object singerObject = doc.getFieldValue("singer");
		if (null != senderObject && null != receiverObject
				&& null != singerObject) {
			String sender = senderObject.toString();
			String receiver = receiverObject.toString();
			String singer = singerObject.toString();
			// output it
			output.collect(new Text(sender), new Text(singer));
			output.collect(new Text(receiver), new Text(singer));
		}

 如果此时进行ant编译,自然会报错,如下:

[javac] /usr/local/music_Name_to_Singer/nutch-1.7/src/java/org/apache/nutch/indexer/IndexerMapReduce.java:53: error: IndexerMapReduce is not abstract and does not override abstract method reduce(Text,Iterator<NutchWritable>,OutputCollector<Text,NutchIndexAction>,Reporter) in Reducer
    [javac] public class IndexerMapReduce extends Configured implements
    [javac]        ^
    [javac] 1 error
    [javac] 1 warning

那是因为我们需要修改一个地方:

IndexerMapReduce.java中的

原先的代码:

job.setOutputFormat(IndexerOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setMapOutputValueClass(NutchWritable.class);
job.setOutputValueClass(NutchWritable.class);

现在要修改为:

 

job.setOutputFormat(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setMapOutputValueClass(NutchWritable.class);
job.setOutputValueClass(Text.class);


以及

public class IndexerMapReduce extends Configured implements
  Mapper<Text, Writable, Text, NutchWritable>,
  Reducer<Text, NutchWritable, Text, NutchIndexAction> {

修改为

public class IndexerMapReduce extends Configured implements
  Mapper<Text, Writable, Text, NutchWritable>,
  Reducer<Text, NutchWritable, Text, Text> {

然后ant

就可以看到

BUILD SUCCESSFUL
Total time: 15 seconds

表明编译成功!

别急着运行,还有一个地方需要修改!

---------------------- 在InexingJob中有如下一些代码:

final Path tmp = new Path("tmp_" + System.currentTimeMillis() + "-"
                + new Random().nextInt());

        FileOutputFormat.setOutputPath(job, tmp);
        try {
            JobClient.runJob(job);
            // do the commits once and for all the reducers in one go
            if (!noCommit) {
                writers.open(job,"commit");
                writers.commit();
            }
            long end = System.currentTimeMillis();
            LOG.info("Indexer: finished at " + sdf.format(end) + ", elapsed: "
                    + TimingUtil.elapsedTime(start, end));
        } finally {
            FileSystem.get(job).delete(tmp, true);
        }

表明,Nutch1.7默认是把输出导向到其它输出的,而不是本地HDFS.

所以FileSystem.get(job).delete(tmp, true);是用来删除此文件的,此时我们需要修改这个地方来保留文件。

不然咱辛辛苦苦写的文件,全被一句话任性的删掉了。

------------------------代码如下:

注意:我这里的需求是输出为当天的目录。所以代码为:

//final Path tmp = new Path("tmp_" + System.currentTimeMillis() + "-"
               // + new Random().nextInt());
        Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
        final Path tmp = new Path(getConf().get("pathPrefix"),"year="+year+"/month="+month+"/day="+day);

        FileOutputFormat.setOutputPath(job, tmp);
        try {
            JobClient.runJob(job);
            // do the commits once and for all the reducers in one go
            if (!noCommit) {
                writers.open(job,"commit");
                writers.commit();
            }
            long end = System.currentTimeMillis();
            LOG.info("Indexer: finished at " + sdf.format(end) + ", elapsed: "
                    + TimingUtil.elapsedTime(start, end));
        } finally {
            //FileSystem.get(job).delete(tmp, true);
        }

此时编译是可以通过的。

好,暂时就是这样,效果图:

 

© 著作权归作者所有

共有 人打赏支持
强子哥哥

强子哥哥

粉丝 859
博文 926
码字总数 640946
作品 8
南京
架构师
Hadoop简要介绍

本文大部分内容都是从官网Hadoop上来的。其中有一篇介绍HDFS的pdf文档,里面对Hadoop介绍的比较全面了。我的这一个系列的Hadoop学习笔记也是从这里一步一步进行下来的,同时又参考了网上的很...

晨曦之光
2012/03/09
168
0
nutch在hadoop下运行问题

nutch运行分布式模式,在hadoop上运行,总是提示38954端口拒绝访问,这端口在哪设置呢?nutch单机模式可以运行,hadoop可以运行,把hadoop的 etc/hadoop/下的文件都复制到nutch的conf下,运行...

极雪寒冬
2015/09/21
258
0
NUTCH公开课:从搜索引擎到网络爬虫

课程背景:Nutch诞生于2002年8月,是Apache旗下的一个用Java实现的开源搜索引擎项目,自Nutch1.2版本之后,Nutch已经从搜索引擎演化为网络爬虫,接着Nutch进一步演化为两大分支版本:1.X和2...

杨尚川
2013/09/12
3.3K
1
Apache Nutch v2.3 发布,Java实现的网络爬虫

Apache Nutch v2.3已经发布了,建议所有使用2.X系列的用户和开发人员升级到这个版本。 这个版本提供了一个基于Apache Wicket的Web管理界面,解决了143个问题,提供了Maven依赖,升级到Gora ...

杨尚川
2015/01/31
18.5K
9
Nutch:从搜索引擎到网络爬虫

开源力量公开课第三十一期- Nutch:从搜索引擎到网络爬虫 开源力量公开课,每周二晚线上线下同时开课,让我们一起向IT技术大牛们学习! 课程题目: 开源力量公开课第三十一期- Nutch:从搜索引...

liuhua0312
2013/09/10
1K
1
Hadoop 之初识Hadoop

Hadoop历史 雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。 随后在2003年Google发表了一篇...

李超
2015/04/02
0
0
Hadoop到底是什么?Hadoop基础知识讲解

Hadoop雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。 随后在2003年Google发表了一篇技术...

袁梓皓
2016/03/15
192
0
Hadoop基础教程之初始Hadoop

Hadoop一直是我想学习的技术,正巧最近项目组要做电子商城,我就开始研究Hadoop,虽然最后鉴定Hadoop不适用我们的项目,但是我会继续研究下去,技多不压身。 《Hadoop基础教程》是我读的第一...

不用真名可好
2016/05/24
69
1
CentoS5.6 X64下架设 Hadoop完全分布式文件系统

前言: Hadoop简介 Hadoop是一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。简单地说来,Hadoo...

crushlinux
2013/10/14
0
0
分布式文件系统--HDFS

Hadoop Distributed File System,简称HDFS,是一个分布式文件系统。HDFS有着高容错性(fault-tolerent)的特点,并且设计用来部署在低廉的(low-cost)硬件上。而且它提供高吞吐量(high th...

匿名
2012/09/10
9.1K
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java8新特性之接口

在JDK8以前,我们定义接口类中,方法都是抽象的,并且不能存在静态方法。所有的方法命名规则基本上都是 public [返回类型] [方法名](参数params) throws [异常类型] {}。 JDK8为接口的定义带...

developlee的潇洒人生
28分钟前
0
0
aop + annotation 实现统一日志记录

aop + annotation 实现统一日志记录 在开发中,我们可能需要记录异常日志。由于异常比较分散,每个 service 方法都可能发生异常,如果我们都去做处理,会出现很多重复编码,也不好维护。这种...

长安一梦
39分钟前
1
0
将博客搬至CSDN

AHUSKY
50分钟前
1
0
Python web框架Django学习(1)

1.Django简介 (1)Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django是一个开放源代码的Web应用框架,由Python写成。 (2...

十年磨一剑3344
今天
0
0
Databook-数据之书

Databook-数据之书 用于数据分析的Jupyter Notebooks。 不需购买服务器,快速开始自己的数据分析过程。 源码:https://github.com/openthings/databook 作者:openthings,https://github.co...

openthings
今天
5
0
Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
今天
1
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
今天
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
今天
0
0
Android Studio+NDK+Cmake 移植FFmpeg-4.0.2命令行工具

一、编译 参考大神的帖子,亲测一次编译成功:https://blog.csdn.net/bobcat_kay/article/details/80889398 鉴于以前查文档的经验,这里附上编写例子的时间:2018年7月22日 我用的是ubantu,...

她叫我小渝
今天
0
0
mysql创建数据库

登录MYSQL mysql -u root -p 脚本创建数据库WeChat,并制定默认的字符集是utf8mb4。 CREATE DATABASE Wechat DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; 授权 grant all......

niithub
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部