大規模なデータでジョブを送信する際に問題が発生した人はいますか。データは非圧縮で約5〜10 TBで、約500Kのファイルにあります。単純なJavaMapReduceジョブを送信しようとすると、ほとんどの場合、getsplits()関数呼び出しに1時間以上かかります。また、ジョブトラッカーに表示されるまでに数時間かかります。この問題を解決するための可能な解決策はありますか?
2 に答える
500k ファイルの場合、これらすべてのファイルを見つけるためにツリー ウォークに多くの時間を費やします。これらのファイルは、InputSplits のリスト (getSplits の結果) に割り当てる必要があります。
トーマスが彼の回答で指摘しているように、ジョブの送信を実行しているマシンで JVM に割り当てられているメモリの量が少ない場合、JVM がガベージ コレクションを実行して構築に必要なメモリを見つけようとする問題が発生します。これらの 500K ファイルの分割。
さらに悪いことに、これらの 500K ファイルが分割可能で、1 つのブロック サイズよりも大きい場合、ファイルを処理するためにさらに多くの入力分割が行われます (サイズが 1GB、ブロック サイズが 256MB のファイルの場合、 ll は、入力形式とファイル圧縮がファイルの分割をサポートしていると仮定して、デフォルトでこのファイルを処理するために 4 つのマップ タスクを取得します)。これがジョブに当てはまる場合 (ジョブに対して生成されたマップ タスクの数を見てください。500k 以上ありますか?)、mapred.min.split.size
構成プロパティを現在のブロックよりも大きいサイズに修正することで、作成されるマッパーを強制的に減らすことができます。サイズ (前の例で 1GB に設定すると、ファイルを処理するマッパーが 4 つではなく 1 つになることを意味します)。これにより、getSplits メソッドのパフォーマンスが向上し、getSplits の結果リストが小さくなり、必要なメモリが少なくなります。
問題の 2 番目の症状は、入力分割をファイル (クライアント側) にシリアル化するのに時間がかかり、次にジョブ トラッカー側で逆シリアル化に時間がかかることです。500K 以上の分割には時間がかかります。また、JVM メモリの制限が低い場合、jobtracker にも同様の GC 問題が発生します。
これは、送信サーバー(またはラップトップクライアント)がどれだけ「強力」であるかに大きく依存します。getSplits呼び出しを高速化するには、RAMとCPUをアップグレードする必要があるかもしれません。
そこでスワップの問題が発生したため、計算に通常の数倍の時間がかかると思います。