代码之家  ›  专栏  ›  技术社区  ›  Eran Kampf

在Hadoop中并行Ruby还原程序?

  •  4
  • Eran Kampf  · 技术社区  · 17 年前

    Ruby中的简单字数缩减器如下所示:

    #!/usr/bin/env ruby
    wordcount = Hash.new
    STDIN.each_line do |line|
    keyval = line.split("|")
    wordcount[keyval[0]] = wordcount[keyval[0]].to_i+keyval[1].to_i
    end
    
    wordcount.each_pair do |word,count|
    puts "#{word}|#{count}"
    end
    

    它在STDIN中获取所有映射器的中间值。不是从一个特定的键。 所以实际上只有一个reducer(不是每个单词或每组单词的reducer)。

    然而,在Java示例中,我看到了这个接口,它以inout的形式获取键和值列表。这意味着中间映射值在reduce和reducer并行运行之前按键分组:

    public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
                public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
                  int sum = 0;
                  while (values.hasNext()) {
                    sum += values.next().get();
                  }
                  output.collect(key, new IntWritable(sum));
                }
              }
    

    这是Java特有的特性吗?或者我可以通过使用Ruby的Hadoop流媒体来实现吗?

    2 回复  |  直到 17 年前
        1
  •  5
  •   Kevin Weil    17 年前

    无论您是否使用流式处理,reducer都将始终并行运行(如果您没有看到这一点,请验证作业配置是否设置为允许多个reduce任务——请参阅集群或作业配置中的mapred.reduce.tasks)。不同之处在于,当您使用Java与流媒体时,框架会为您更好地打包。

    对于Java,reduce任务获取一个迭代器,该迭代器覆盖特定键的所有值。这使得在reduce任务中对map输出求和时,很容易遍历这些值。在流式处理中,您实际上只是得到一个键值对流。你 保证值将按键排序,并且给定键的值不会在reduce任务中分割,但所需的任何状态跟踪都由您决定。例如,在Java中,映射输出以符号形式到达减速机

    键1,{val1,val2,val3}

    使用流媒体,您的输出看起来像

    键1,val1 键1,键2 键1,val3 键2,键8

    例如,要编写一个减缩器来计算每个键的值之和,需要一个变量来存储看到的最后一个键,并需要一个变量来存储值之和。每次读取新的键值对时,都要执行以下操作:

    1. 如果是这样,请输出密钥和当前总和,并将总和重置为零。
    2. 将当前值添加到总和,并将最后一个键设置为当前键。

    嗯。

        2
  •  1
  •   sris    17 年前

    我自己还没有尝试过Hadoop流媒体,但通过阅读文档,我认为您可以实现类似的并行行为。

    尝试使用 -verbose 选项以获取有关实际情况的更多信息。您还可以尝试使用 -D mapred.reduce.tasks=X 选项,其中X是所需的减速器数量。