2

私の仕事への入力がファイルセット[a、b、c、d]である場合、ソートへの入力は厳密に[map(a.0)、map(a.1)、map(b.0)、map( b.1)、マップ(c.0)、マップ(c.1)、マップ(d.0)、マップ(d.1)]?

私の動機は、行が[キー、値]である一連のファイル(もちろんブロックに分割されます)を持つことです。ここで、キーと値はそれぞれ単純な文字列です。明示的な順序定義フィールドがないにもかかわらず、入力に存在する順序でキーごとにレデューサーでこれらの値を連結したいと考えています。

アドバイスをいただければ幸いです。これは、Google にとって難しいクエリであることがわかっています。

入力形式

A First
A Another
A Third
B First
C First
C Another

望ましい出力

A First,Another,Third
B First
C First,Another

繰り返しますが、ファイルが別々のブロックに保存されている場合、First-Third を正しい順序で取得できるかどうかはわかりません。

4

2 に答える 2

0

この問題の解決策の1つは、ファイル内のTextInputFormatのバイトオフセットを複合キーの一部として使用し、2次ソートを使用して、値が順番にレデューサーに送信されるようにすることです。そうすることで、レデューサーが、ファイルに入った順序で必要なキーによって分割された入力を確認できるようになります。複数の入力ファイルがある場合、新しいファイルごとにバイトカウンターがリセットされるため、このアプローチは機能しません。

ストリーミングAPIを使用すると-inputformat TextInputFormat -D stream.map.input.ignoreKey=false、実際にバイトオフセットをキーとして取得できるように、ジョブに渡す必要があります(デフォルトでは、入力フォーマットがTextInputFormatの場合、PipeMapperはキーを提供しません。明示的にTextInputFormatフラグを設定した場合でもしたがって、追加のignoreKeyフラグを設定する必要があります)。

マッパーから複数のキーを発行する場合は、必ず次のフラグを設定して、出力が最初のキーで分割され、レデューサーで1番目と2番目にソートされるようにしてください。

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner
-D stream.num.map.output.key.fields=2
-D mapred.text.key.partitioner.options="-k1,1"
-D mapred.output.key.comparator.class="org.apache.hadoop.mapred.lib.KeyFieldBasedComparator"
-D mapreduce.partition.keycomparator.options="-k1 -k2n"
于 2012-07-13T16:15:41.593 に答える
0

いいえ、Hadoopの標準データフロー(つまり、標準ソーター、パーティショナー、グルーパー)を使用して、値がこの順序になるという保証はありません。保証されるのは、キーの順序(A、B、C)だけです。

必要なことを実現するには、独自のソーターを作成し、キーに値(First、Second、Third)を含める必要があります=>新しいキーは次のようになります。

  "A First"
  "A Second"
  ...

ただし、この場合の問題は、これらのキーが異なるパーティションに配置されることです(標準のハッシュパーティショナーが「最初の」を1つのパーティションに、「2番目の」を別のパーティションに配布する可能性が非常に高い)ので、この問題を回避します。また、キーの最初の部分(つまり、A)のみを使用してパーティショニングを行う独自のパーティショナーを接続する必要があります。ハタも定義する必要があります。そうしないと、「最初の」、「2番目の」が同じreduce呼び出しに一緒に渡されません。

したがって、map関数の出力は次のようになります。

 "A First"    First
 "A Second"   Second
 ...

つまり、マッパーが出力する値はそのままにしておく必要があります。そうしないと、レデューサーで値を取得できません。

于 2012-07-13T10:22:39.280 に答える