2011-09-15 46 views
3

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

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

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

除此之外,这看起来并不起作用,因为这些键未映射到特定的缩减器。

在其他地方的答案是编写一个自定义的分区类,将每个需要的键值映射到一个特定的reducer。这将是伟大的,除了我需要使用Python与流,我不能包括一个自定义流媒体jar在我的工作,所以这似乎不是一个选项。

我看到in the hadoop docs有一个可用的备用分区类,它可以启用辅助排序,但对于我来说,使用基于默认或键字段的分区程序来确保每个键结束了它自己的reducer而无需编写一个java类并使用自定义流式jar。

任何建议将不胜感激。

实例

映射器输出:

CSV2 \ tfieldA,fieldB,fieldC csv1 \ tfield1,FIELD2,字段3,字段4 csv3 \ tfieldRed,fieldGreen ...

问题是,如果我有3个reducer我结束了像这样的密钥分配:

reducer1  reducer2  recuder3 
csv1   csv2 
csv3 

一个reducer获取两种不同的密钥类型,一个reducer根本没有收到任何数据。这是因为哈希(密钥csv1)mod 3和哈希(密钥csv2)mod 3导致相同的值。

+0

的Hadoop将默认发送的所有数据使用相同的密钥相同的减速。你能举出一些你想要做什么以及它不工作的例子吗? – cftarnas

回答

1

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

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

+0

这正是我所需要的,并将完全解决我的问题,但我无法弄清楚如何使用它与流。人们建议用MultipleOutputFormat代码创建一个新的streaming.jar文件,但是我还没有找到任何好的教程,如果我能避免它,我真的宁愿不去那么远。 – underrun

+0

我正在做这个答案 - 如果您创建自己的jar,并创建一个MultipleOutputFormat的子类,该子类创建与密钥一致的目录/文件名并生成一个空实际密钥,那么您可以在流中使用它。我想避免Java,幸运的是有一个clojure项目,它完全符合我的需求:https://github.com/jblomo/oddjob ...有关如何构建/使用它的说明位于github页面上。 – underrun

1

如果你被卡住流,并且不能包含自定义分区任何外部罐子,那么这可能不会给你想要的方式工作,没有一些黑客。

如果这些都是绝对的要求,你可以解决这个,但它很混乱。

这里是你可以做什么:

Hadoop的,默认情况下,使用散列分区,就像这样:

key.hashCode() % numReducers

所以你可以选择键,它们散列为1,2,和3个(或三个数字,如x % 3 = 1, 2, 3)。这是一个令人讨厌的黑客攻击,除非你没有别的选择,否则我不会建议。

+0

这实际上是我决定我需要做到这一点。但它非常笨重,我决定使用一个简单的reducer输出最终的csv行的原始密钥,然后通过cat part-00000 |运行我的输出文件。 grep key |为每个键削减-f 2> key.csv'。我减少了并行度,我必须对输出结果进行后处理,但无论我做什么似乎都很拙劣和难看。 – underrun

1

如果你想自定义输出到不同的CSV文件,可以直接写(与API)到HDFS。正如你所知道的Hadoop密钥和相关的值列表传递给单个约简任务。在减少代码时,检查一下键是否一样写入同一个文件。如果有另一个键,手动创建新文件并写入它。不要紧,你有多少reducer

+0

这似乎不是一个坏主意......感谢您的建议! – underrun

+0

良好的通话。使用Python流式缩减器,他可以使用-file参数将(压缩的)Python HDFS库提供给任务节点,然后使用Python zipimport模块导入它们。 – ajduff574

相关问题