【发布时间】:2013-02-26 22:26:41
【问题描述】:
因为它突出 MultipleTextOutputFormat 尚未迁移到新的 API。因此,如果我们需要根据动态写入的键值来选择输出目录和输出文件名,那么新的 mapreduce API 有什么替代方案?
【问题讨论】:
因为它突出 MultipleTextOutputFormat 尚未迁移到新的 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 方法要求键与映射输出键的类型相同(如果您在映射器中使用它)或与reduce 输出键的类型相同(如果您在减速机)。该值也必须以类似的方式输入。
后一种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,因此所有baseOutputPaths 都严格包含在传递给-output 参数的路径中。
有关如何设置和正确使用 MultipleOutputs 的更多详细信息,请参阅我找到的这段代码(不是我的,但我发现它很有帮助;不使用不同的输出目录)。 https://github.com/rystsov/learning-hadoop/blob/master/src/main/java/com/twitter/rystsov/mr/MultipulOutputExample.java
【讨论】:
baseOutputPath,它成功输出到不同的文件。
类似于:Hadoop Reducer: How can I output to multiple directories using speculative execution?
基本上,您可以直接从 reducer 写入 HDFS - 您只需要警惕推测执行并唯一地命名您的文件,然后您需要实现自己的 OutputCommitter 来清理中止的尝试(这是如果您有真正动态的输出文件夹,则最困难的部分是 - 您需要逐步浏览每个文件夹并删除与中止/失败任务相关的尝试)。一个简单的解决方案是关闭推测执行
【讨论】:
要获得最佳答案,请参阅 Hadoop - 权威指南第 3 版。(从第 253 页开始。)
摘自 HDG 书 -
“在旧的 MapReduce API 中,有两个类用于产生多个输出:MultipleOutputFormat 和 MultipleOutputs。简单来说,MultipleOutputs 功能更全,但 MultipleOutputFormat 对输出目录结构和文件命名的控制更多。MultipleOutputs 中的新 API 结合了旧 API 中两个多输出类的最佳特性。”
它有一个关于如何使用 MultipleOutputs API 控制目录结构、文件命名和输出格式的示例。
HTH。
【讨论】:
run() 中使用MultipleOutputs.addNamedOutput() 来做到这一点。我可能在这里遗漏了一些东西,但不想发表这样的声明,如果它在其他地方很容易找到,你至少可以发布一个链接。