2013-02-26 64 views
8

由于它突出了MultipleTextOutputFormat尚未迁移到新的API。因此,如果我们需要选择一个输出目录并根据正在写入的键值输出fiename,那么我们对新的mapreduce API有何选择?新API中的MultipleTextOutputFormat替代

回答

4

我正在使用AWS EMR Hadoop 1.0.3,并且可以根据k/v对指定不同的目录和文件。使用以下任一功能从MultipleOutputs类:

public void write(KEYOUT key, VALUEOUT value, String baseOutputPath) 

public <K,V> void write(String namedOutput, K key, V value, 
         String baseOutputPath) 

前者write方法要求的关键,是相同的类型作为地图输出密钥(如果你正使用该在映射器中)或与缩小输出键相同的类型(如果您正在使用reducer)。该值也必须以类似的方式输入。

后者write方法需要键/值类型时设定使用addNamedOutput函数MultipleObjects静态属性,以匹配所指定的类型:

public static void addNamedOutput(Job job, 
           String namedOutput, 
           Class<? extends OutputFormat> outputFormatClass, 
           Class<?> keyClass, 
           Class<?> valueClass) 

所以如果你需要不同的输出类型比Context使用,您必须使用后者write方法。

的窍门能让不同的输出目录是通过一个baseOutputPath包含目录分隔符,就像这样:

multipleOutputs.write("output1", key, value, "dir1/part"); 

在我而言,这创建了一个名为“DIR1 /一部分-R-00000”的文件。

我没有成功使用包含..目录的baseOutputPath,因此所有baseOutputPath严格包含在传递给-output参数的路径中。

有关如何设置和正确使用MultipleOutputs的更多细节,请参阅我找到的代码(不是我的,但我发现它非常有用;不使用不同的输出目录)。 https://github.com/rystsov/learning-hadoop/blob/master/src/main/java/com/twitter/rystsov/mr/MultipulOutputExample.java

+0

我忘了提及我测试了基于键/值数据改变'baseOutputPath',并成功输出到不同的文件。 – Eddified 2013-10-11 17:34:00

+0

我很高兴你提到它,我已经发现它最终虽然:) – Amar 2013-10-15 18:52:45

+0

非常感谢“dir1/part”部分,不会想到这一点! – ssgao 2014-05-01 02:21:20

0

类似:Hadoop Reducer: How can I output to multiple directories using speculative execution?

基本上你可以直接从减速到HDFS写 - 你只需要警惕投机性执行和唯一命名您的文件,那么你就需要实现你自己的OutputCommitter清理中止的尝试(如果您有真正的动态输出文件夹,这是最困难的部分 - 您需要遍历每个文件夹并删除与中止/失败任务关联的尝试)。一个简单的解决方法是关闭推测执行

+0

这听起来不简单:P对于MultipleTextOutputFormat任何解决方法?或者我们可以使用新的API实现类似MultipleTextOutputFormat的东西吗? – Amar 2013-02-27 09:56:23

+0

正如多个输出的javadoc中所述,我在作业和缩减器中添加了下面的代码,它工作正常。在作业中: MultipleOutputs.addNamedOutput(job,namedoutputstring,outputformatclass,keyclass,valueclass); 在减速器中: mos = new MultipleOutputs (context); ... /*在运行时计算*/baseoutput =“abc/xyz/filename”; mos.write(key,value,baseOutput); – techuser 2013-03-06 19:34:10

+0

不要忘记清理()中的mos.close()。 – 2013-10-11 20:44:27

-1

为最佳答案,转向Hadoop的 - (首发控卫253)的权威指南第三版

一个从HDG书摘 -

“在旧的MapReduce API中,有两个类用于生成多个输出:MultipleOutputFormat和MultipleOutputs。简而言之,MultipleOutputs功能更全面,但MultipleOutputFormat更多地控制输出目录结构和文件命名。在旧API中结合了两个多输出类的最佳特性。“

它举例说明如何使用MultipleOutputs API控制目录结构,文件命名和输出格式。

HTH。

+0

MultipleOutputs是否允许根据键值对快速决定输出文件夹名称或文件名?我不这么认为,如果有任何方法请让我知道。 – Amar 2013-02-27 09:30:25

+0

是的,伙计,我找不到它!使用MultipleOutputs,你只能写入一组*预定义的文件路径。你可以在'run()'中使用'MultipleOutputs.addNamedOutput()'来做到这一点。我可能会在这里丢失一些东西,但不是做出这样的陈述,如果它很容易在其他地方找到,那么你至少可以发布一个链接。 – Amar 2013-02-27 16:24:30

+0

我也怀疑你已经使用了MultipleTextOutputFormat或MultipleOutputs!在阅读本书时,它明确指出,就在示例之前:*与MutipleTextOutputFormat相比,使用MultipleOutputs *时对输出命名的控制较少。 – Amar 2013-02-27 16:30:33