1

私は Hadoop で Reducer を作成しており、その入力値を使用して、要素のリストをエンコードするバイト配列を作成しています。データを書き込むバッファーのサイズは、リデューサーが受け取る値の数によって異なります。そのサイズを事前にメモリに割り当てておくと効率的ですが、「foreach」ステートメントで反復処理を行わないと、値がいくつあるかわかりません。

Hadoop 出力は HBase テーブルです。

更新: マッパーでデータを処理した後、リデューサー キーにはべき乗則分布があります。これは、少数のキーのみが多くの値 (最大 9000) を持つことを意味しますが、それらのほとんどは少数の値しか持ちません。4096 バイトのバッファーを割り当てると、97.73% の値が収まることに気付きました。それらの残りの部分については、すべての値が収まるまで、容量が 2 倍のバッファーの再割り当てを試みることができます。私のテストケースでは、キーに 9000 個の値がある最悪のケースでは、メモリを 6 回再割り当てすることでこれを達成できます。

4

2 に答える 2

2

バイト配列を割り当てた後、とにかく for-each を使用してそれらを処理すると仮定しますが、メモリ内のすべてのレコードをバッファリングする必要はありません (イテレータのみをループできるため)値のコレクションから一度戻ってください)。したがって、次のことができます。

  1. すべての入力レコードを出力し、マップ出力と同じ値クラスのレコードにカウントを出力するカウント リデューサーを実行し、カウントを配置するカスタム ソートを使用して、その結果に対して「リデュースのみ」のジョブを実行します。最初(推奨)
  2. Hadoop で取得した組み込みの並べ替えをオーバーライドして、並べ替え中にカウントし、そのカウント レコードを出力の最初のレコードとして挿入します (オーバーライドを達成する方法は完全にはわかりませんが、何でも可能です)。
  3. 値が一意である場合、呼び出される値のハッシュを保持するステートフルなソート コンパレータを使用できる可能性があります (これは非常にハッキーでエラーが発生しやすいようですが、 2 次ソートは、1 つの JVM 内の 1 つのクラス・ローダーに限定されます)
  4. バイト配列よりも柔軟なデータ構造を使用するようにレデューサーを設計し、必要に応じて出力する前に結果をバイト配列に変換します (強くお勧めします)。
于 2012-08-04T05:25:22.750 に答える
0

次のパラダイムを使用できます。

マップ: 各マッパーはキーから整数へのマップを保持します。ここで、M[k] は特定のキー k で送信される値の数です。入力の最後に、マップはキーと値のペア (k, M[k]) も送信します。

並べ替え: ペア (k, M[k]) がペア (k, あなたの値) の前に来るように、二次並べ替えを使用します。

Reduce: キー k を見ているとします。次に、リデューサーはまず、さまざまなマッパーからのカウント M[k] を集計して、数値 n を取得します。お探しの番号です。これで、データ構造を作成して計算を実行できます。

于 2013-08-18T01:21:07.877 に答える