AND OR  

Hadoop とは大量のデータを複数のマシンに分散して処理できるオープンソースのプラットフォームです。

ここではHadoopを運用していく上で必要な知識をメモ程度を残していきます。

パラメータ関連

  • ''hadoop-env.sh''
    ''パラメータ''''説明''''補足''
    HADOOP_OPTSデーモンのJava起動オプションヒープサイズを設定したり、並列GC、コンカレントGCを使用するなど
    -server -XX:+UseParallelGC -XX:+UseConcMarkSweepGC -Xms1500m -Xmx1500m
  • ''hadoop-site.xml''
    ''パラメータ''''説明''''補足''
    mapred.tasktracker (map,reduce).tasks.maximum個々のTaskTrackerで同時に走るMap/Reduceの最大タスク数デフォルトは2、コア数-1くらいが良い感じ
    mapred.child.java.optsMapReduceの子JVMのオプションメモリが足りない時に、最大ヒープサイズを設定するなど
    mapred.child.java.opts の設定は、JobConf実行時に設定可。
    (hadoop-site.xml の設定項目は実行時に設定できるものとできないものがある)

SequenceFile

SequenceFile は、<key, value>形式でデータを保持する。テキストをそのままMapで読み込むと、keyにバイトオフセット、valueに入力テキストが入るが、SequenceFile形式だとkey, valueをそのままMapの入力とすることができる。また、圧縮していても各ノードに分散される(gzipは分散されない)。hadoop fs -text とすれば、コマンドラインからテキスト形式で内容を出力できる。

  • Jobのinputとoutputを SequenceFile 形式にする
  • テキスト形式で内容を確認
$ hadoop fs -text SequenceFile.out

HadoopではgzipファイルをMapに直接入力することができ、自動で展開してくれる。ただし、分割して各ノードに分散してくれない。1つのgzipファイルは1つのノードで処理される。

圧縮

  • 可能な限りスプリット可能な圧縮形式で圧縮
  • 空間,時間効率のバランスを考えるとLZO推奨
  • サイズの大きなgzipファイルを入力にしてはいけない
  • gzipファイルを利用する場合には、1ブロックサイズにマッチしていると効果的
  • 出力データも圧縮

ブロックサイズ最適化

Hadoop は大きなファイルをシーケンシャルに読み書きするのに適した設計がされているので、小さいファイルを大量に扱うのは苦手。空間効率が悪い上に NameSpace を大量に消費して NameNode に負荷をかける。さらに MapReduce では、デフォルトで1つのファイルにつき少なくとも1つの MapTask が立ち上がってしまい非効率。

  • 保存領域を節約するためHadoopアーカイブを利用
  • CombineFileInputFormat を利用
    (小さなファイルをまとめて一つの InputSplit にすることで MapTask 数を削減できる)
  • mapred.min.split.size をブロックサイズ以上に設定
    (ブロックサイズ以上にスプリットされるので MapTask 数を削減できる)

Map出力データ

  • Map出力データは圧縮すること
    Map出力ファイルはローカルに書き出されるので、データ量の削減はディスクI/Oの削減に効果がある。また、シャッフル処理されるときネットワークを通過する場合が多いので、データ転送量の削減にも効果的。ディスクI/Oと比べてCPUに余裕があれば圧縮処理はボトルネックになりにくい。

ジョブ一般

  • 小さなデータでもクラスタ外のデータを都度参照してはいけない
    処理に必要な小さなデータについては、DistributedCache を利用する。
  • Mapタスク数がデータ量に見合っているか注意すること
  • Reduceタスク数が多すぎないか注意すること
    TaskTracker毎にReduceタスク数ぶんだけMap出力パーティションが作成されるので、シャッフルフェイズがボトルネックとなる可能性がある。

Hive

  • 同じテーブルに対して複数回クエリを発行する場合には、ストレージ形式にSequenceFileを圧縮設定で用いる。
  • クエリを複数実行し、かつ中間データが必要ない場合には、Pigで記述出来ないか検討する。