hadoop 流确保每个 reducer 一个键

Posted

技术标签:

【中文标题】hadoop 流确保每个 reducer 一个键【英文标题】:hadoop streaming ensuring one key per reducer 【发布时间】:2011-09-15 13:46:44 【问题描述】:

我有一个映射器,它在处理数据时将输出分类为 3 种不同的类型(类型是输出键)。我的目标是通过 reducer 创建 3 个不同的 csv 文件,每个文件都包含一个键的所有数据和一个标题行。

键值可以更改并且是文本字符串。

现在,理想情况下,我希望拥有 3 个不同的 reducer,每个 reducer 将只获得一个包含整个值列表的键。

除了,这似乎不起作用,因为键没有映射到特定的减速器。

在其他地方对此的答案是编写一个自定义分区器类,它将每个所需的键值映射到特定的减速器。这会很棒,除了我需要在 python 中使用流式传输并且我无法在我的工作中包含自定义流式传输 jar,因此这似乎不是一个选项。

我看到in the hadoop docs 有一个可用的备用分区器类可以启用二级排序,但对我来说并不是很明显可以使用基于默认或键字段的分区器来确保每个key 最终在它自己的 reducer 上结束,无需编写 java 类并使用自定义流 jar。

任何建议将不胜感激。

示例

映射器输出:

csv2\tfieldA,fieldB,fieldC csv1\tfield1,field2,field3,field4 csv3\tfieldRed,fieldGreen ...

问题是,如果我有 3 个减速器,我最终会得到这样的密钥分配:

reducer1        reducer2        recuder3
csv1            csv2
csv3

一个reducer 获得两种不同的key 类型,一个reducer 根本没有数据发送给它。这是因为 hash(key csv1) mod 3 和 hash(key csv2) mod 3 结果相同。

【问题讨论】:

Hadoop 默认将所有具有相同键的数据发送到同一个reducer。你能举一些例子说明你正在尝试做什么以及它是如何不起作用的吗? 【参考方案1】:

我很确定 MultipleOutputFormat [1] 可以在流媒体下使用。这将解决您的大部分问题。

http://hadoop.apache.org/common/docs/r0.20.1/api/org/apache/hadoop/mapred/lib/MultipleOutputFormat.html

【讨论】:

这正是我所需要的,并且可以完全解决我的问题,但我不知道如何将它与流媒体一起使用。人们建议创建一个包含 MultipleOutputFormat 代码的新 streaming.jar 文件,但我没有找到任何好的教程,如果可以避免的话,我真的不想走那么远。 我正在回答这个问题——如果您使用 MultipleOutputFormat 的子类创建自己的 jar 并根据键创建目录/文件名并生成 null 实际键,则可以在流式传输中使用它.我想避免使用 java,幸运的是,有一个 clojure 项目可以满足我的需要:github.com/jblomo/oddjob ...有关如何构建/使用它的说明在 github 页面上。 嘿,链接好像坏了。 这个答案已有 7 年历史,所以我想你不想再使用 r0.20。【参考方案2】:

如果您坚持使用流式传输,并且无法为自定义分区器包含任何外部 jar,那么如果没有一些 hack,这可能无法按照您希望的方式工作。

如果这些是绝对要求,您可以解决这个问题,但这很麻烦。

您可以这样做:

默认情况下,Hadoop 使用散列分区器,如下所示:

key.hashCode() % numReducers

因此,您可以选择散列为 1、2 和 3(或三个数字,例如 x % 3 = 1, 2, 3)的键。这是一个令人讨厌的 hack,除非您别无选择,否则我不会建议您这样做。

【讨论】:

这基本上是我决定实现这一目标所需要做的。但这太麻烦了,我决定使用单个减速器输出带有最终 csv 行的原始键,然后通过cat part-00000 | grep key | cut -f 2 > key.csv 为每个键运行我的输出文件。我在减速器中失去了并行性,我必须对我的输出进行后处理,但无论我做什么都看起来很丑陋。【参考方案3】:

如果您想要自定义输出到不同的 csv 文件,您可以直接写入(使用 API)到 hdfs。如您所知,hadoop 将键和关联的值列表传递给单个 reduce 任务。在减少代码中,检查,而键是相同的写入同一个文件。如果另一个密钥来了,手动创建新文件并写入它。你有多少个减速器并不重要

【讨论】:

这似乎不是一个坏主意...感谢您的建议! 好电话。使用 Python 流式缩减器,他可以使用 -file 参数将(压缩的)Python HDFS 库传送到任务节点,然后使用 Python zipimport 模块导入它们。

以上是关于hadoop 流确保每个 reducer 一个键的主要内容,如果未能解决你的问题,请参考以下文章

在 Hadoop 二级排序中将键值路由到正确的 Reducer

如何在 Hadoop 流中设置每个节点的最大减速器数量?

使用shell脚本的Hadoop流:reducer因错误而失败:没有这样的文件或目录

为同一个 reducer 函数收集不同的键 - HADOOP

第五篇:Hadoop流

Hadoop 多文件输出 MultipleOutputFormat