0

私のコードは 10000 行を実行します。

マッパーの擬似コード:

int rows=0;
map()
   {rows++}  
cleanup(Context c)
   {print(rows)}

このコードは次を出力します。

2669
3354
3353
621
(sum=9997)

なぜ合計が9997なのですか?

レデューサーの擬似コード:

int rows=0;
reduce()
   {rows++}  
cleanup(Context c)
   {print(rows)}

レデューサーは次のように出力します: 3354

他のすべてのデータはどこにありますか?

編集 1

私は主な問題を発見しました。

私のせいは、送信されるキーが行の番号であることです。マッパーがcleanup()関数を呼び出すと、行のカウンターがリセットされます (アプリケーションのドライバーに保持されます)。したがって、キーは一意ではありません。マップ関数のパラメーターからキーを送信することで解決できますか? cleanup()がこのパラメーターをリセットするとは思わない。

代わりに、アプリケーションのドライバーでグローバル変数を使用すると、同期の問題が発生しますか?

編集 2

私のコードは 10000 行 (および 1 ヘッダー行) を実行します

ドライバーの擬似コード:

public static enum COUNTER {ROW};

マッパーの擬似コード:

map()
   {row=context.getCounter(RWDriver.COUNTER.ROW).increment(1);
    context.write(row,new Text(...))
   }     
cleanup(Context c)
   {print(c.getCounter(RWDriver.COUNTER.ROW).getValue());}

このコードは次を出力します。

2670
3355
3354
622
(sum=10001 correct)

2670,3355 の後、バッファーがいっぱいになり、MapReduce はカウンター ROW を自動的に 0 にリセットします。実際の行数が必要ですが、この方法は機能しません。

4

1 に答える 1

0

データの解釈が間違っている可能性があります。

Map-Reduce Framework カウンターまたはユーザー定義カウンターのいずれかを使用する必要があります。


Map-Reduce フレームワーク カウンター

Map input records
Map output records
Map output bytes
Reduce input groups
Reduce input records
Reduce output records

ユーザー定義カウンター

class mapper()
{
static enum Counters { INPUT_LINES }
map()
{
  context.getCounter(Counters.INPUT_LINES).increment(1);
}

同様に Reducer でも。

カウンターの値を取得する

Configuration conf = new Configuration();
Cluster cluster = new Cluster(conf);
Job job = Job.getInstance(cluster,conf);
result = job.waitForCompletion(true);
...
Counters counters = job.getCounters();
for (CounterGroup group : counters) {
  System.out.println("* Counter Group: " + group.getDisplayName() + " (" + group.getName() + ")");
  System.out.println("  number of counters in this group: " + group.size());
  for (Counter counter : group) {
    System.out.println("  - " + counter.getDisplayName() + ": " + counter.getName() + ": "+counter.getValue());
  }
}
于 2013-01-17T13:44:01.327 に答える