multitextoutputformat尚未迁移到新的API。因此,如果我们需要根据动态写入的键值选择输出目录和输出文件名,那么我们使用新的mapreduce API有什么替代方案呢?
我正在使用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
方法要求键与map输出键的类型相同(如果您在mapper中使用它)或与reduce输出键的类型相同(如果您在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/part-r-00000"的文件。
我没有成功地使用包含..
目录的baseOutputPath
,因此所有baseOutputPath
都严格包含在传递给-output
参数的路径中。
有关如何设置和正确使用MultipleOutputs的更多详细信息,请参阅我发现的此代码(不是我的,但我发现它非常有帮助;不使用不同的输出目录)。https://github.com/rystsov/learning-hadoop/blob/master/src/main/java/com/twitter/rystsov/mr/MultipulOutputExample.java
类似于:Hadoop Reducer:我如何使用推测执行输出到多个目录?
基本上,你可以直接从你的reducer中写入HDFS -你只需要警惕预测执行和唯一命名你的文件,然后你需要实现你自己的OutputCommitter来清理放弃的尝试(这是最困难的部分,如果你有真正的动态输出文件夹-你需要遍历每个文件夹并删除与放弃/失败任务相关的尝试)。一个简单的解决方案是关闭推测执行
要获得最佳答案,请参阅Hadoop -权威指南第3版(第253页开始)
HDG书籍节选-
"在旧的MapReduce API中,有两个类用于产生多个输出:MultipleOutputFormat和MultipleOutputs。简而言之,MultipleOutputs功能更全面,但MultipleOutputFormat对输出目录结构和文件命名有更多的控制。新API中的MultipleOutputs结合了旧API中两个多输出类的最佳特性。"
它有一个关于如何使用MultipleOutputs API控制目录结构、文件命名和输出格式的示例。
HTH .