我对hadoop流非常陌生,在分区方面有一些困难。
根据在一行中找到的内容,我的mapper函数要么返回
key1, 0, somegeneralvalues # some kind of "header" line where linetype = 0
或
key1, 1, value1, value2, othervalues... # "data" line, different values, linetype =1
为了正确地减少,我需要对具有相同键1的所有行进行分组,并按value1、value2和线型(0或1)对它们进行排序,例如:
1 0 foo bar... # header first
1 1 888 999.... # data line, with lower value1
1 1 999 111.... # a few datalines may follow. Sort by value1,value2 should be performed
------------ #possible partition here, and only here in this example
2 0 baz foobar....
2 1 123 888...
2 1 123 999...
2 1 456 111...
有没有办法确保这样的划分?到目前为止,我已经尝试过一些选择,比如
-partitioner,'org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner'
-D stream.num.map.output.key.fields=4 # please use 4 fields to sort data
-D mapred.text.key.partitioner.options=-k1,1 # please make partitions based on first key
或者
-D num.key.fields.for.partition=1 # Seriously, please group by key1 !
只会带来愤怒和绝望。
值得一提的是,如果我使用cat data | mapper | sort | reduce,并且使用amazon elastic map reduce ruby客户机,那么我的脚本可以正常工作,因此我将使用
--arg '-D','options' for the ruby script.
任何帮助都将不胜感激!提前谢谢
2条答案
按热度按时间5lwkijsr1#
多亏了ryanbwork我才解决了这个问题。耶!
正确的想法确实是创建一个由值串联而成的键。进一步说,还可以创建一个
然后可以将选项传递给hadoop,以便它可以按键的第一个“部分”进行分区。如果我没有误解的话,看起来
这个解决方案基于ryanbwork所说的,允许创建更多的缩减器,同时确保数据被正确地分割和排序。
rkue9o1l2#
读完这篇文章后,我建议修改Map器,让它返回一对“键”,其中的“键”包括键值、线型值和value1/value2值,所有这些值都连接在一起。你应该保持这一对的“价值”部分不变。例如,您将返回以下对来表示前两个示例:
现在,如果您使用一个reducer,那么您的所有记录都将被发送到同一个reduce任务,并根据它们的“键”按字母顺序排序。这将满足您的要求,即对按键排序,然后按线型排序,然后按值1排序,最后按值2排序,您可以在对的“值”部分分别访问这些值。我对不同的内置partioner/sort类不是很熟悉,但我假设您可以使用默认值并使其正常工作。