Hadoop チューニング

GMOアドマーケティングのT.Cです。

入社してから今までPHP, Ruby On Rails, Java, Spark, JavaScriptなどの様々な言語を使った開発に関わることでどんどん開発の幅が広くなりましたが、プロジェクトで運用しているHadoopクラスタについては関わる機会がなかったので、以前から興味を持っていたこともあって今回勉強してみました。

勉強する中でもっとも面白かったのはチューニングに関してでした。
クラスタの規模やアプリケーションの特性などでそれぞれ違いますが、やはりHadoopで決めた各Defaultの設定で各処理が期待した以上に早く終わるケースがある場合と、逆に処理が遅いケースもあるでしょう。
こういった場合にチューニングを行って最適化していけば、よりデータの処理時間を減らしてoutputが早く取得できたり、その分別の処理を行える余裕もできたりするかもしれません。
そこで今回は、数あるチューニング方法の中の一部の方法について説明します。

1. Blockサイズ

1.1. 説明
■ ファイルはBlockという単位で分割されてHDFSに保存されるが1つのブロックのサイズは64MB
■ Blockのサイズを調整することで処理スピードの改善及びNameNodeのメタデータ管理にもいい効果が出る

1-2. チューニング方法
■ 大容量のファイルの場合やBlockの数が多い場合は、各Blockを保存するための他のDataNodeとの通信回数が多くなる
■ Blockのサイズを大きくしてBlock数とDateNodeとの通信回数も減らして処理時間を短縮できる
■ 大容量のファイルを構成するBlock数が少なくなるのでNameNodeが管理するメタデータ量が減らせる
(ヒープメモリの使用量が減る)
■ 設定はhdfs-site.xml or Configurationクラスを利用する(dfs.blocksize)

1-3. 注意点
■ Blockサイズが増えると使用可能な並列処理が減少するので適切に調整する
■ Blockサイズが小さすぎると、膨大なメタデータの量をNameNodeが管理することになる
■ 設定を変えてもすでにHDFSに保存したBlockのサイズは変更されない
(削除して再保存する方法などがある)

2. Mapタスクの処理結果を複製するスレッド数

2.1. 説明
■ shuffleでReduceタスクはMapタスクで処理したデータを複製用スレッドを生成してHTTPで取得するのでその数を調整することでスピードをあげることができる

2-2. チューニング方法
■ 複製用のスレッド数を増やすことでデータの複製が早くなる
■ 複製スレッドのデフォルト数は5だがmapred-site.xmlを利用して設定する(mapred.reduce.parallel.copies)

2-3. 注意点
■ 一気に大量のデータを取得しようとすると、ネットワークに負荷かかかってしまうので複製用スレッド数を調整しながら一気に複製するデータの量を調整する

3. NameNodeのヒープメモリ

3-1. 説明
■ NameNodeはメタデータをヒープメモリで管理するのでフロック数やファイル数を減らすことでヒープメモリの使用量を減らせる

3-2. チューニング方法
■ ブロックのサイズより小さく、同じ種類のファイルの場合、一つのファイルに併合する
■ ブロックサイズを大きくしてファイルを構成するブロック数を減らす
■ HDFS上にあるファイルを圧縮(gzip, zlib2など)してファイルのサイズとブロック数を減らせる

3-3. 注意点
■ ブロックサイズを大きくするのは「1-3. 注意点」を参照

4. Garbage Collection


4-1. 説明
■ 新しく生成したObjはEdenに保存されてGC(Minor GC)で生き残ったObjはSurvivor1領域に移動
■ 次のGCでEdenとSurvivor1領域で生き残ったObjをSurvivor2に移動
■ Survivor領域が持つ基準値を超過、一定回数のGCにも生き残ったObjはOld領域に保存される
■ 上記の作業を繰り返してOld領域がFullになるとFull GCが発生する
■ New領域とOld領域の比率を適切に設定することでメモリをうまく活用できる

4-2. チューニング方法
■ NameNodeはメタデータをヒープメモリで管理するのでHDFSに永久的に保存するファイルの多い場合は(= Old領域に保存される)、Old領域を増やしてFull GC回数を減らす
■ HDFSに短期的に保存するファイルの多い場合は、NameNodeのNew領域を増やしてOld領域に移動するObj数を減らしFull GC回数を減らす
■ MapReduceのJobが完了すると、ヒープメモリから情報を削除するのでJobTrackerとTaskTrackerのNew領域を増やしてこの領域で管理できるようにする

4-3. 注意点
■ 調整はNew領域とOld領域の比率とGC方式(Parallel GCなどを意味)の調整が重要
■ たとえば、Old領域を増やしすぎると、もちろんFull GCの回数は減るが、実行時間(stop the world)は増えてしまい他の問題が発生するなど、逆に元より悪化する可能性もあるので十分に検討する

 

まとめ

上記以外にもMapタスクでバッファー関連設定を調整し、ディスクへの出力を制御したり、OSレベルのチューニングしたり色々なチューニングの方法が存在しますが、クラスターの規模やアプリケーション、ネットワークやMapReduceの処理対象など、様々な環境や状況によってチューニング方法が異なり、設定を変更した時の長所と短所も様々なので、それらを理解して適切にチューニングすることが大事だと思います。