2

私はHadoopを初めて使用します。私は単語数を使いましたが、今は変更を加えたいと思います。

テキストファイルで最も多く出現した単語を取得したい。の場合、通常の単語数プログラムは出力を提供します:

a 1
b 4
c 2

出力だけが出るプログラムを書きたい

b 4

ここに私のレデューサー関数::

public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> 
{

 int max_sum=0;
 Text max_occured_key;

 public void reduce(Text key, Iterable<IntWritable> values, Context context) 
  throws IOException, InterruptedException 
  {
    int sum = 0;
    for (IntWritable val : values) 
    {
        sum += val.get();           
    }
    if(sum > max_sum)
    {
        max_sum = sum;
        max_occured_key = key;

    }

    context.write(max_occured_key, new IntWritable(max_sum));
    //context.write(key, new IntWritable(sum));

  }

}

しかし、それは正しい出力を与えていません。誰かがplzを助けることができますか?

4

1 に答える 1

5

これまでの最大値を各 reduce 関数の最後に書き出しているため、reducer ごとに複数のエントリを取得できます。キーの参照を max_occured_key 変数に (値をコピーするのではなく) コピーしているため、参照の再利用の問題も発生しています。

おそらく次のように修正する必要があります。

  • max_occured_key構築時に変数を初期化します(空のテキストに)
  • equals 代入を使用する代わりに呼び出すmax_occured_key.set(key);- key パラメーターの参照は reduce メソッドのすべての反復で再利用されるため、実際のオブジェクトは同じままで、基礎となるコンテンツだけが反復ごとに修正されます。
  • クリーンアップをオーバーライドしmethod、context.write 呼び出しをそのメソッドに移動して、リデューサーごとに 1 つの K,V 出力ペアのみを取得できるようにします。

例えば:

@Override
protected void cleanup(Context context) {
  context.write(max_occured_key, new IntWritable(max_sum));
}

クリーンアップ メソッドは、すべてのデータがマップまたはリデュース タスクを通過すると呼び出されます (そして、タスク インスタンスごとに呼び出されます (したがって、10 個のレデューサーを指定した場合、このメソッドはインスタンスごとに呼び出されます)。

于 2013-01-14T12:17:13.843 に答える