Hadoopジョブは、実行には成功していても非効率な処理による性能遅延やマシンリソースの過剰な消費が発生している場合があります。そのため以下ような観点でデバッグを行います。
タスクが各TaskTrackerに均等に割り当たっているか
失敗したタスク試行がないか
Mapタスクが遅延していないか
Reduceタスクの処理時間が均等か
作業ファイルが過剰に作成されていないか
上記の確認には、bdpp_prtjobhistツールの利用をおすすめします。
参照
bdpp_prtjobhistツールの使用方法については、「G.1 ジョブヒストリログ可視化ツール」を参照してください。
タスクが各TaskTrackerに均等に割り当たっているか
TaskTrackerにタスクが均等に割り当たっていない場合、処理時間が遅延します。
bdpp_prtjobhistで出力したxlsxファイルの2シート目以降の『タイムチャート』を参照し、当該ジョブに含まれるタスクが、すべてのスレーブサーバに均等に割り当たっているかを確認します。タスクが割り当たっていないスレーブサーバが存在する場合には、TaskTrackerプロセスが起動されているか、TaskTrackerがJobTrackerに稼働中と認識されているかを確認してください。
また、特に入力データ量が少なく処理時間の短いジョブでは、総タスク数を総スロット数で割った剰余分のタスクが任意のTaskTrackerに割り当たることでタスク試行の終了が他のTaskTrackerと比較して遅れて見える場合があります。これは、同時に総スロット数以上のタスクは試行できないためです。これを解決するには以下の対策を実施します。
Mapタスクの場合、Hadoopジョブに適切なpdfs.fs.local.block.size(pdfs-site.xml)を指定することで剰余分のMapタスクが発生しないようにMapタスク数を調整します。
Reduceタスクの場合、Hadoopジョブに適切なmapred.reduce.tasks(mapred-site.xml)を指定することで剰余分のタスクが発生しないようにReduceタスク数を調整します。
参考
TaskTrackerプロセスが起動されているかを確認するにはbdpp_statコマンドを使用します。詳細は「A.15 bdpp_stat」を参照してください。
TaskTrackerがJobTrackerに稼働中と認識されているかを確認するにはhadoop jobコマンドを使用します。詳細は「17.3.4 TaskTrackerプロセス異常時の動作」を参照してください。
pdfs.fs.local.block.size、mapred.reduce.tasksの詳細は、「17.5.1 Hadoopジョブとタスク」を参照してください。
失敗したタスク試行はないか
Hadoopジョブとしては成功していても内部的にタスク試行がリトライされている場合、本来の処理時間よりも遅延していることになります。
bdpp_prtjobhistで出力したxlsxファイルの1シート目の『FAILED_MAPS』『FAILED_REDUCES』が0以外になっていないかを確認します。0以外の場合には2シート目以降を参照し失敗したタスク試行IDを特定し、失敗の原因を解消してください。
参考
タスク試行IDは以下の形式となっています。
attempt_YYYYMMDDhhmm_NNNN_X_OOOOOO_P
YYYYMMDDhhmm = JobTrackerの起動時刻 NNNN = JobTrackerの起動以降に依頼されたHadoopジョブの通番 X = [m|r] m:Mapタスク|r:Reduceタスク OOOOOO = Hadoopジョブ内でのタスクの通番 P = タスク内でのタスク試行の通番
上記タスク試行は、タスクID “task_YYYYMMDDhhmm_NNNN_X_OOOOOO” のタスクに対応しています。
タスク試行の失敗原因は、タスクログ、TaskTrackerログ、およびシステムログの内容などから特定します。各ログファイルの出力ディレクトリは「17.4.3 ログファイルの一覧」を参照してください。また、OSのsarコマンド等でスレーブサーバの稼働状況を監視している場合には、それも参考となります。
Mapタスクが遅延していないか
一部のMapタスクが他と比較して著しく処理遅延している場合、スレーブサーバ、TaskTracker、およびMapReduceアプリケーションに問題が発生している可能性があります。
bdpp_prtjobhistで出力したxlsxファイルの2シート目以降の『タイムチャート』およびMapタスクの『total-time』を参照し、他と比較して処理が遅延しているMapタスクがないかを確認します。遅延している場合はタスク試行IDを特定し、遅延の原因を解消します。
参考
タスク試行の遅延原因は、タスクログ、TaskTrackerログ、およびシステムログの内容などから特定します。各ログファイルの出力ディレクトリは「17.4.3 ログファイルの一覧」を参照してください。また、OSのsarコマンド等でスレーブサーバの稼働状況を監視している場合には、それも参考となります。
Reduceタスクの処理時間が均等か
一部のReduceタスクが他と比較して著しく処理遅延している場合、Mapタスクで設定したKeyの分布に偏りがあり該当するReduceタスクに処理データ量が偏っている可能性があります。または、スレーブサーバ、TaskTracker、およびMapReduceアプリケーションに問題が発生している可能性もあります。
bdpp_prtjobhistで出力したxlsxファイルの2シート目以降の『タイムチャート』およびReduceタスクの『total-time』、『shuffle-time』、『sort-time』よび『reduce-time』を参照し、他と比較して処理が遅延しているReduceタスクがないかを確認します。
処理データ量の偏りは、出力ファイルのサイズの差がヒントになります。サイズが偏っている場合にはMapReduceアプリケーションのMapタスクで設定するKeyを変更するか、Keyの分布に合ったPartitionerを作成してください。Reduceタスクの出力ファイル名は以下の形式となっており、Hadoopジョブに指定した出力ディレクトリ内の出力ファイルとタスク試行を対応づけることができます。
part-r-OOOOO
“OOOOO”の部分は、Reduceタスク試行IDのHadoopジョブ内でのタスクの通番部分に対応します。(Reduceタスク試行IDの通番と桁数は異なります)
処理データ量に偏りがない場合は、遅延しているタスク試行IDを特定し遅延の原因を解消します。
注意
Reduceタスク数がReduceスロット数よりも多い場合、各スロットで異なるReduceタスクのタスク試行が順番に複数回実行されます。この場合、各Reduceスロットの先頭Reduceタスク試行のshuffle-timeが遅延しているように見えますが異常ではありません。これは、先頭のReduceタスク試行のshuffle-timeには、shuffleフェーズがMapタスクの終了を待ちあわせるための時間が含まれているためです。
この場合、Mapタスクの終了から先頭のReduceタスク試行のshuffleフェーズが終了するまでの時間が、2回目降のReduceタスクのshuffle-timeと同等以下であることを確認してください。
各スレーブサーバでのReduceタスクの起動時刻は概ね3秒間隔となります。これは、TaskTrackerがJobTrackerに対して3秒おきにタスク割り当てを1つずつ要求するためです。たとえば、Reduceスロット数が3の場合、3つめのReduceタスクは、最初のReduceタスクの起動から約6秒後となります。非常に処理時間の短いHadoopジョブでは、この時刻差が全体時間に影響する場合があります。
そのような場合、mapreduce.tasktracker.outofband.heartbeat(mapred-site.xml)にtrueを指定します。これにより、タスクが割り当てられていないスロットを持つTaskTrackerは即時にタスク割り当てをJobTrackerに要求するため、起動の時刻差を短縮することができます。本製品のデフォルトの設定はfalseです。
参考
タスク試行の遅延原因は、タスクログ、TaskTrackerログ、およびシステムログの内容などから特定します。各ログファイルの出力ディレクトリは「17.4.3 ログファイルの一覧」を参照してください。また、OSのsarコマンド等でスレーブサーバの稼働状況を監視している場合には、それも参考となります。
作業ファイルが過剰に作成されていないか
作業ファイルは、Mapタスクがメモリ上でソート処理できなくなった段階で書き出されます。Mapタスクに十分なメモリが割り当てられている場合、作業ファイルに書き出されるデータ数はMapタスクが出力したデータ数と同等になりますが、Mapタスクが出力するデータ量や個々のデータのサイズに依存して必要以上のデータ数を書き出してしまう場合があります。
bdpp_prtjobhistで出力したxlsxファイルの1シート目の『Map output records』と『Spilled Records』が同等かを確認します。同等でない場合には、以下のプロパティを変更し同等となるよう調整します。
io.sort.mb(mapred-site.xml)
Mapタスクに割り当てるソート用メモリ量をmapred.child.java.opts -Xmx(mapred-site.xml)の範囲内で調整します。デフォルトの設定ではmapred.child.java.opts -Xmxの50%の量をio.sort.mbとして使用します。増加させた分Mapタスクの実データ処理で利用可能なJava Heapは減少します。
io.sort.record.percent(mapred-site.xml)
io.sort.mbに指定されたメモリのうち、管理領域として使用する割合を指定します。本製品のデフォルトの設定は0.05(5%)です。Mapタスクが出力するデータサイズが小さい場合、相対的に管理領域の消費が大きくなります。管理領域が不足した場合、io.sort.mbに余裕があるにも関わらず作業ファイルが作成されます。最適値は以下のように算出します。
16 / (16 + 『Map output bytes』/『Map output records』)
pdfs.fs.local.block.size(pdfs-site.xml)
Mapタスクが入力するデータ量(数)を調整し、結果としてMapタスクが出力するデータ量(数)がio.sort.mbの80%以内となるよう調整します。