我有一个映射器,在处理数据时,将输出分为3种不同的类型(类型是输出键) . 我的目标是通过reducer创建3个不同的csv文件,每个文件包含一个带有 Headers 行的键的所有数据 .
键值可以更改,并且是文本字符串 .
现在,理想情况下,我希望有3个不同的reducer,每个reducer只有一个键,它的整个值列表 .
除此之外,这似乎不起作用,因为键不会映射到特定的reducer .
其他地方的答案是编写一个自定义分区程序类,将每个所需的键值映射到特定的reducer . 这将是伟大的,除了我需要使用与python的流,我不能在我的工作中包括自定义流媒体jar,所以这似乎不是一个选项 .
我看到in the hadoop docs有一个可用的备用分区器类可以启用二级排序,但它不是自己的reducer而不编写java类并使用自定义流jar .
任何建议将不胜感激 .
Examples :
映射器输出:
csv2 \ tfieldA,fieldB,fieldC csv1 \ tfield1,field2,field3,field4 csv3 \ tfieldRed,fieldGreen ...
问题是,如果我有3个reducer,我最终会得到这样的密钥分配:
reducer1 reducer2 recuder3
csv1 csv2
csv3
一个reducer获取两个不同的密钥类型,一个reducer根本没有发送数据 . 这是因为散列(key csv1)mod 3和hash(key csv2)mod 3导致相同的值 .
3 回答
我很确定MultipleOutputFormat [1]可以在流媒体下使用 . 这将解决你的大部分问题 .
http://hadoop.apache.org/common/docs/r0.20.1/api/org/apache/hadoop/mapred/lib/MultipleOutputFormat.html
如果您遇到流式传输,并且无法为自定义分区程序包含任何外部jar,那么这可能不会像您希望的那样在没有一些黑客的情况下工作 .
如果这些是绝对要求,你可以解决这个问题,但这很麻烦 .
这是你可以做的:
默认情况下,Hadoop使用散列分区程序,如下所示:
key.hashCode() % numReducers
所以你可以选择键,使它们散列为1,2和3(或三个数字,如
x % 3 = 1, 2, 3
) . 这是一个讨厌的黑客,除非你没有其他选择,否则我不建议 .如果您想要自定义输出到不同的csv文件,您可以直接写入(使用API)到hdfs . 如您所知,hadoop将密钥和关联值列表传递给单个reduce任务 . 在reduce代码中,检查,而key是相同的写入同一文件 . 如果出现另一个密钥,请手动创建新文件并写入其中 . 你有多少减速器并不重要