值得注意的是,MultipleTextOutputFormat 尚未迁移到新的 API。因此,如果我们需要根据动态写入的键值来选择输出目录和输出文件名,那么新的 mapreduce API 有什么替代方案?
3 回答
我使用的是 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
一种方法要求 key 与 map 输出 key 的类型相同(如果您在 mapper 中使用它)或与 reduce 输出 key 相同的类型(如果您在 reducer 中使用它)。该值也必须以类似的方式输入。
后一种方法要求键/值类型与使用该函数write
设置 MultipleObjects 静态属性时指定的类型相匹配:addNamedOutput
public static void addNamedOutput(Job job,
String namedOutput,
Class<? extends OutputFormat> outputFormatClass,
Class<?> keyClass,
Class<?> valueClass)
因此,如果您需要与使用不同的输出类型,Context
则必须使用后一种write
方法。
获取不同输出目录的技巧是传递baseOutputPath
包含目录分隔符的 a,如下所示:
multipleOutputs.write("output1", key, value, "dir1/part");
就我而言,这创建了名为“dir1/part-r-00000”的文件。
我没有成功使用baseOutputPath
包含..
目录的a,所以所有baseOutputPath
s都严格包含在传递给-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。