hadoop streaming:如何给reducer提供关键值列表?

时间:2011-10-05 17:41:23

标签: python hadoop mapreduce hadoop-streaming

因此,当我们使用Java编写map/reduce程序时,地图会收集数据,而reducer会收到每个键的值列表,例如

Map(k, v) -> k1, v1  
    then shuffle and sort happens  
    then reducer gets it  

reduce(k1, List<values>)  

继续努力。但使用python streaming是否也可以这样做?我使用this作为参考,似乎reducer获取命令行

提供的每行数据

4 个答案:

答案 0 :(得分:5)

可能这可以帮到你。我从apache中找到了这个...... org

自定义将线分割为键/值对的方法 如前所述,当Map / Reduce框架从映射器的标准输出中读取一行时,它会将该行拆分为键/值对。默认情况下,直到第一个制表符的行的前缀是键,行的其余部分(不包括制表符)是值。

但是,您可以自定义此默认值。您可以指定除制表符(默认值)以外的字段分隔符,并且可以指定第n个(n> = 1)字符而不是行中的第一个字符(默认值)作为键和值之间的分隔符。例如:

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper org.apache.hadoop.mapred.lib.IdentityMapper \
    -reducer org.apache.hadoop.mapred.lib.IdentityReducer \
    -D stream.map.output.field.separator=. \
    -D stream.num.map.output.key.fields=4 

在上面的示例中,-D stream.map.output.field.separator=.指定“。”作为地图输出的字段分隔符,以及直到第四个“。”的前缀。在一行中将是键,行的其余部分(不包括第四个“。”)将是值。如果一行少于四个“。”,则整行将成为键,值将为空文本对象(如新文本(“”)创建的那个)。

同样,您可以使用-D stream.reduce.output.field.separator=SEP-D stream.num.reduce.output.fields=NUM将reduce输出行中的第n个字段分隔符指定为键和值之间的分隔符。

同样,您可以指定stream.map.input.field.separatorstream.reduce.input.field.separator作为map / reduce输入的输入分隔符。默认情况下,分隔符是制表符。

答案 1 :(得分:1)

在Hadoop Streaming中,映射器将键值对写入sys.stdout。 Hadoop执行shuffle并排序并将结果定向到sys.stdin中的映射器。你如何实际处理地图和减少完全取决于你,只要你遵循该模型(映射到stdout,从stdin减少)。这就是为什么它可以在命令行上通过cat data | map | sort | reduce独立于Hadoop进行测试。

reducer的输入与映射的键值对相同​​,但是有序。您可以迭代结果并累积总结,如示例所示,或者您可以进一步将输入传递给itertools.groupby(),这将为您提供相当于您习惯的k1, List<values>输入,哪个适用于reduce()内置。

关键是要由你来实现reduce。

答案 2 :(得分:1)

PipeReducer是Hadoop流的reducer实现。 reducer得到键/值,迭代它并以键/值而不是键/值发送到STDIN。这是Hadoop流的默认行为。除非已修改Hadoop代码,否则我看不到任何更改此选项的选项。

public void reduce(Object key, Iterator values, OutputCollector output,
                 Reporter reporter) throws IOException {

    .....
    while (values.hasNext()) {
    .....
        inWriter_.writeKey(key);
        inWriter_.writeValue(val);
    .....      
    }
}

答案 3 :(得分:0)

根据Hadoop的流媒体参考here

  • 默认情况下,密钥是第一个标签前行的前缀。
  

当Map / Reduce框架从mapper的stdout读取一行时,它会将该行拆分为键/值对。默认情况下,直到第一个制表符的行的前缀是键,行的其余部分(不包括制表符)是值。

  • 可以自定义分隔符和键位置。
  

但是,您可以自定义此默认值。您可以指定除制表符(默认值)以外的字段分隔符,并且可以指定第n个(n> = 1)字符而不是行中的第一个字符(默认值)作为键和值之间的分隔符。例如:

  • 示例代码:

    $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \ -D stream.map.output.field.separator=. \ -D stream.num.map.output.key.fields=4 \ -input myInputDirs \ -output myOutputDir \ -mapper org.apache.hadoop.mapred.lib.IdentityMapper \ -reducer org.apache.hadoop.mapred.lib.IdentityReducer