4

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にすべてのマッパーの中間値を取得します。特定のキーからではありません。したがって、実際には、すべてに対して1つのレデューサーしかありません(単語ごとまたは単語のセットごとにレデューサーはありません)。

ただし、Javaの例では、キーと値のリストをinoutとして取得するこのインターフェースを見ました。つまり、中間マップ値は、reducedと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ストリーミングでそれを行うことはできますか?

4

2 に答える 2

5

ストリーミングを使用しているかどうかに関係なく、レデューサーは常に並行して実行されます(これが表示されない場合は、ジョブ構成が複数のリデュースタスクを許可するように設定されていることを確認してください-クラスターまたはジョブ構成のmapred.reduce.tasksを参照してください)。違いは、Javaを使用する場合とストリーミングを使用する場合に、フレームワークがパッケージをもう少しうまくパッケージ化することです。

Javaの場合、reduceタスクは、特定のキーのすべての値に対してイテレーターを取得します。これにより、たとえば、reduceタスクでマップ出力を合計する場合に、値を簡単にたどることができます。ストリーミングでは、文字通り、キーと値のペアのストリームを取得します。値はキーごとに並べ替えられ、特定のキーについてはreduceタスク間で分割されないこと保証されますが、必要な状態追跡はあなた次第です。たとえば、Javaでは、マップ出力はシンボリックに次の形式でレデューサーに送られます。

key1、{val1、val2、val3} key2、{val7、val8}

ストリーミングを使用すると、代わりに出力は次のようになります。

key1、val1 key1、val2 key1、val3 key2、val7 key2、val8

たとえば、各キーの値の合計を計算するレデューサーを作成するには、最後に表示したキーを格納するための変数と、合計を格納するための変数が必要になります。新しいキーと値のペアを読み取るたびに、次のことを行います。

  1. キーが最後のキーと異なるかどうかを確認します。
  2. その場合は、キーと現在の合計を出力し、合計をゼロにリセットします。
  3. 現在の値を合計に追加し、最後のキーを現在のキーに設定します。

HTH。

于 2009-05-09T19:13:10.013 に答える
1

私はHadoopStreamingを自分で試したことはありませんが、ドキュメントを読むと、同様の並列動作を実現できると思います。

ストリーミングでは、関連付けられた値を持つキーを各レデューサーに渡す代わりに、マッパーの出力をキーごとにグループ化します。また、同じキーを持つ値が複数のレデューサーに分割されないことも保証されます。これは通常のHadoop機能とは多少異なりますが、それでも、リデュース作業は複数のレデューサーに分散されます。

-verboseこのオプションを使用して、実際に何が起こっているかについての詳細情報を取得してみてください。-D mapred.reduce.tasks=XXが必要なレデューサーの数であるオプションを試すこともできます。

于 2009-05-08T13:22:49.350 に答える