Hadoop MapReduce - 每个输入的一个输出文件

问题描述:

我是Hadoop的新手,我试图弄清楚它是如何工作的。至于练习,我应该实现类似于WordCount-Example的东西。任务是读入几个文件,执行WordCount并为每个输入文件编写一个输出文件。 Hadoop使用组合器并将映射部分的输出作为reducer的输入进行混洗,然后写入一个输出文件(我猜是针对正在运行的每个实例)。我想知道是否有可能为每个输入文件写入一个输出文件(因此请保留inputfile1的文字并将结果写入outputfile1等等)。是否可以覆盖Combiner-Class或者是否有其他解决方案(我不确定这是否应该在Hadoop任务中解决,但这是练习)。Hadoop MapReduce - 每个输入的一个输出文件

谢谢...

map.input.file环境参数都有映射器正在处理的文件名。在映射器中获取此值,并将其用作映射器的输出键,然后使用单个文件中的所有k/v转到一个缩减器。

映射器中的代码。顺便说一句,我正在使用旧的MR API

@Override 
public void configure(JobConf conf) { 
    this.conf = conf; 
} 

@Override. 
public void map(................) throws IOException { 

     String filename = conf.get("map.input.file"); 
     output.collect(new Text(filename), value); 
} 

并使用MultipleOutputFormat,这允许写入作业的多个输出文件。文件名可以从输出键和值中派生。

+0

谢谢,我认为这是最好的主意。也许我会使用旧的API,因为它看起来更容易处理,但首先我会看看0.20 – spooky 2012-01-18 12:00:37

Hadoop'块'数据到配置大小的块。默认是64MB块。您可能会发现这会导致您的方法出现问题。每个映射器可能只获得一个文件的一部分。如果文件小于64MB(或配置了任何值),则每个映射器只会获得1个文件。

我有一个非常类似的约束;我需要一组文件(链中前一个减速器的输出)完全由一个映射器处理。我在我的解决方案中使用了< 64MB的事实 我的解决方案的主要目标是,我将它设置为为映射器提供它需要处理的文件名,映射器的内部将它加载/读取文件。这允许单个映射器处理整个文件 - 它不是分布式处理文件,而是受到“我不想单个文件分发”的限制 - 它可以工作。 :)

我已经启动了我的MR的过程写出文件的文件名称处理成单个文件。这些文件写入的地方就是输入目录。由于每个文件是< 64MB,那么将为每个文件生成一个映射器。进程只会被调用一次(因为文件中只有一个入口)。
然后,我将传递给映射器的值,打开文件并执行我需要的任何映射。 由于hadoop试图聪明地了解它如何执行Map/Reduce过程,因此可能需要指定要使用的缩减器的数量,以便每个映射器都转到单个缩减器。这可以通过mapred.reduce.tasks配置来设置。我通过job.setNumReduceTasks("mapred.reduce.tasks",[NUMBER OF FILES HERE]);

这样做我的过程有一些额外的要求/限制,可能使这个特定的解决方案吸引人;但是以1:1到1:out为例;我已经完成了,上面已经列出了基础知识。

HTH

+0

感谢您的意见。通过setNumReduceTasks,我可以获得尽可能多的输出文件。然而,减速器的输入仍然混合/混洗。我没有检查我的映射器的输出,看起来像一个映射器正在处理两个文件(但这不应该是问题)。而且只处理一个文件的映射器的结果与其他映射器的结果混合在一起。我可以阻止Hadoop执行此操作吗(混洗/合并?也许设置合成器类?) 您是否只获取所有文件名并将它们传递给映射器?或者我错过了什么?也许另一个conf值被设置? – spooky 2012-01-17 01:09:14

+0

要强制使用特定的缩减器,请在写入输出时使每个映射器使用特定的键。相同的键将转到同一个映射器。您可以在每个作业的conf中传递不同的值,然后将该值用作关键字。这将导致每个映射器的输出都转到单个reducer(根据我的经验)。 – Nija 2012-01-17 01:14:54

+1

将文件名传递给映射器以便单个映射器处理文件不是有效的方法。没有数据本地化,并且会有数据更混乱。解决的一个方法是将依赖文件捆绑到1(gz,tar)中,并从FileInputFormat#isSplitable方法返回false。 – 2012-01-17 04:00:04