Spark, SQL on Hadoop etc. Advent Calendar 2014 - Qiita 10日目の記事です。
とあるプロジェクトにて、パフォーマンスチューニングのために実施した7つのことをまとめました。
この内容はCloudera World Tokyo 2014でお話しさせていただいた内容を再編したものです。
登壇資料 - Hadoopで作る広告分析プラットフォーム
登壇の様子 - 国内最大級のHadoop関連カンファレンスに登壇してきました!
##1.YARNが利用可能なリソースの変更
YARNではMR1と異なりスロットではなくコンテナという概念でリソースが管理されます。
以下のパラメータでノードマネージャがコンテナに利用可能なメモリ量、CPU数を変更しました。
yarn.nodemanager.resource.memory-mb
yarn.nodemanager.resource.cpu-vcores
##2.クエリパラメータの変更
###2.1.Mapperあたりの最大読み取り量を変更
以下のクエリパラメータを利用して1Mapperあたりの入力サイズを制限することでMapperの同時起動数を増加させました。
mapreduce.input.fileinputformat.split.maxsize
###2.2.Reducer数の変更
以下のクエリパラメータを利用してreducer数を変更しました。
mapred.reduce.tasks
##3.ファイルフォーマットの変更
同一データを異なるファイルフォーマットのテーブルに格納して検証を行いました。
検証したのは以下の4フォーマットです。
RCFile, SequenceFile, Avro, Parquet
RCFile - 弊社環境では最も性能が良かった
SequenceFile - RCFileより少しだけ性能が低かった
Avro, Parquet - 書き込み性能が大幅にダウン
##4.バケット化
バケット化を利用すると指定した列のハッシュ値を元にバケット(データブロック)が作成されます。
テーブルをJOINする場合、結合に使う列がバケット化されていればテーブル全体をフェッチする必要がなくなるのでJOIN処理が効率的に行えます。
残念ながら弊社の環境では効果がありませんでした。
Sort Merge Bucket Map Join
結合対象の列がバケット化されており、かつソートされているとJOINがさらに効率化されます。
しかし、こちらも弊社環境では効果がありませんでした。
##5.ファイルのマージ
small files problem対策として以下のクエリパラメータを利用してファイルのマージを行いました。
hive.merge.mapfiles=true
hive.merge.mapredfiles=true
hive.merge.size.per.task=xxx
hive.merge.smallfiles.avgsize=xxx
※ただしファイルマージステップが実行されるのでINSERTクエリの処理時間が若干増加しました。
##6.レプリカ数の変更
HDFSではブロックを複数ノードにレプリケーションする事で耐障害性を高めています。
このレプリケーション数をテーブルの用途に応じて変更して検証を行いました。
###6.1.ワークテーブルのレプリケーション数を1に変更
ワークテーブルはバッチ処理の都度生成し直すのでレプリケーション数を1とすることでレプリケーション時間の短縮を試みました。
###6.2.頻繁に読み込むテーブルのレプリケーション数をノード数と一致させた
頻繁に読み込むテーブルのレプリケーション数をノード数と一致させることで、各ノードがローカルからデータをロードできるようにしました。(ただし、レプリケーション時間が増加します)
バッチ全体で見た場合にさほど効果が得られなかったため、採用を見送りました。
##7.UDF(User Defined Function)の作成
PHPで作成したストリーミング処理をUDFに書き換えることで、処理時間を40%程削減できました。
これは、
・UDFではHiveQLを処理するタスクと同一のプロセスで処理が行われる
(ストリーミング処理では標準入出力を介した外部プロセスとのデータ受け渡しを行う)
・PHPとJavaの処理性能の差によるものだと考えています。
以上、弊社で試した7つのことでした。