3

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

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

现在,理想情况下,我想拥有 3 个不同的减速器,每个减速器只能获得一个键,它的整个值列表。

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

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

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

任何建议将不胜感激。

例子

映射器输出:

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 产生相同的值。

4

3 回答 3

1

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

如果这些是绝对要求,你可以绕过这个,但它很混乱。

以下是您可以执行的操作:

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

key.hashCode() % numReducers

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

于 2011-09-18T03:33:17.893 回答
1

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

于 2011-09-20T12:26:57.757 回答
1

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

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

于 2011-10-24T21:58:09.503 回答