web-dev-qa-db-ja.com

Hadoopジョブのシャッフル/ソートフェーズを最適化する方法

単一ノードのHadoopジョブを使用してデータの準備を行っています。私のジョブのマッパー/コンバイナーは多くのキー(5Mまたは6M以上)を出力し、明らかにジョブの進行が遅いか、失敗することさえあります。マッピングフェーズは最大120のマッパーで実行され、レデューサーは1つだけです(これらは自動的に決定され、値を設定していません)。シャッフル/ソートフェーズがより効率的に行われるように、ジョブを最適化したいと思います。 mapreduce.task.io.sort.mbを300mに増やしましたが、その値がマッパーヒープよりも大きかったため、ジョブは失敗しました。次に、mapred.child.Java.optsを-Xmx1024mに設定しましたが、出力コレクターを初期化できなかったため、再び失敗しました。これらのシナリオのベストプラクティスは何ですか?

7
HHH

まず、単一ノードクラスターを使用しているため、実行できる最適化はあまりありません。単一ノードクラスター上のコンテナー/スロットの数は限られており、処理するデータの量(500万から600万キー)に対して、ジョブは常に低速で実行され、失敗する可能性もあります。

完全に分散されたHadoopセットアップについて、この質問に答えます。 「HadoopTheDefinitive Guide」という本には、シャッフルとソートのフェーズを調整するために読む必要のあるセクション(「シャッフルとソート」)があります。私の答えは、主にこのセクションの内容と、MapReduceジョブの調整に関する私自身の経験に影響されます。

シャッフルとソートの効率を達成するには、次の操作を実行できます。

  • Combiner:コンバイナーはマッパー側の出力をマージするため、コンバイナーを使用すると、各レデューサーに転送されるデータの量が削減されます。
  • レデューサーの数:レデューサーの最適な数を選択します。データサイズが大きい場合、1つのレデューサーはお勧めできません。また、レデューサーの数はマッパー側のパーティションの数も決定するため、レデューサーの数を多く設定することはお勧めできません。こちらのリンクをご覧ください: https://github.com/paulhoule/infovore/wiki/Choosing-the-number-of-reducers
  • いつレデューサーを開始するか:;いつreduceタスクを開始するかを制御できます。これは構成によって決定されますmapreduce.job.reduce.slowstart.completedmapsYARNで。マッパーの特定の割合が完了するまで、レデューサーは起動しません。デフォルトでは「0.05」に設定されています(これは、マッパーの5%が完了した後にレデューサーが開始することを意味します)。レデューサーが早期に開始された場合、すべてのマッパーが完了するまで、ほとんどのレデューサーはアイドル状態です。また、レデューサーはスロットを消費する可能性があり、そうでなければマッパーが処理に使用する可能性があります。これを制御することで、マッパー/レデューサースロットを最適に使用し、シャッフル中に費やす時間を改善できます。
  • マッパー出力の圧縮:マッパー出力を圧縮することをお勧めします(構成によって決定されます:mapreduce.map.output.compress)、より少ないデータがディスクに書き込まれ、レデューサーに転送されるようにします。
  • Tune config "mapreduce.task.io.sort.mb":ソート中にマッパーが使用するバッファーサイズを増やします。これにより、ディスクへの流出の数が減ります。
  • Tune config "mapreduce.reduce.input.buffer.percent":reduceタスクのメモリ要件が少ない場合は、この値を高く設定できますパーセンテージ。つまり、削減フェーズ中(シャッフルフェーズ後)にマップ出力を保持するためにより多くのヒープが使用されるため、ディスクへのスピルの数が削減されます。
  • Tune config "mapreduce.reduce.shuffle.parallelcopies":マップ出力をレデューサーにコピーするために使用されるスレッドの数。こちらのリンクを確認してください: mapred.reduce.parallel.copiesを調整する方法は?

以下は、シャッフルおよびソートフェーズのパフォーマンスを向上させるために調整できるその他の構成パラメーターです(これらの構成の説明はこちらを参照してください: https://hadoop.Apache.org/docs/r2.4.1/hadoop-mapreduce -client/hadoop-mapreduce-client-core/mapred-default.xml ):

  • mapreduce.map.sort.spill.percent:マッパーが使用するメモリ内バッファのしきい値を決定します。このしきい値に達すると、バッファの内容がディスクに流出します。したがって、この値はディスクへの流出の数を決定します
  • mapreduce.task.io.sort.factor:ソート中に一度にマージされるストリームの最小数。したがって、レデューサー側では、50個のマッパー出力があり、この値が10に設定されている場合、5ラウンドのマージが行われます(マージラウンドでは平均10ファイル)。
  • mapreduce.shuffle.max.threads:マップ出力をレデューサーにコピーするためのワーカースレッドの数。
  • mapreduce.reduce.shuffle.input.buffer.percent:レデューサーでのシャッフルフェーズ中に、マップ出力を格納するために使用するヒープの量。この設定は、ディスクに流出する前にメモリに保持できるマッパー出力の量を決定します。
  • mapreduce.reduce.shuffle.merge.percent:マージおよびディスクへのスピルのプロセスを開始するためのしきい値
  • mapreduce.reduce.merge.inmem.threshold:マージプロセスを開始するために必要なマップ出力の数。どちらかの場合mapreduce.reduce.shuffle.merge.percentまたはmapreduce.reduce.merge.inmem.thresholdに達すると、マップ出力がマージされ、ディスクにスピルされます。
15

デフォルトでは、mapreduceはほとんどのシナリオで問題となる1つのレデューサーのみを選択します。

レデューサーの数をより高い値に設定してコードを変更することもできますjob.setNumReduceTasks(24);

または実行hadoop jar <jarfilename> <class> -Dmapreduce.job.reduces=24 <parameters>

削減の数を正確に判断するには、データを理解する必要があります。 Mapreduceフレームワークは、分割サイズに基づいてマッパーの数を選択しますが、reduceは開発者または運用チームが明示的に設定する必要があります。