MapReduceの中間データを保持する(2)

昨年の夏、ブログ、MapReduceの中間データを保持する、を書いてからその後全く確認をしていなかったところ、何とCDH4.1.1で動かないことが判明!(当時はCDH4のリリース前だったので、CDH3で検証していた)

結果として原因は些細なことでしたが、かなり試行錯誤してしまい、MLなどで情報収集しても解決せずでした。同様の問題に悩んでいる方もいらっしゃるようです。訂正かつ補足します。

2. 条件に基づいてファイルを残す
(続きを読む)

[Tips] ドライバでReducerを指定しなかったら?

トレーニングをやっていると、やさしいものから超絶難しいものまでいろんな質問がやってきます。
以下、調べたものをシェアします。

今回はMapReduce編:

Q. reduceの数を0に指定した場合、reducerは呼ばれるのか?
A. -D mapred.reduce.tasks=0などを使用してreduce数をゼロに指定した場合、
 reduceタスクが実行されることはありません。

Q.ドライバーコードでreducerを指定しない場合は何が呼ばれる?
A.reducerをドライバーコードに記述しなかった場合、newAPIでは
 org.apache.hadoop.mapreduce.Reducer.javaのデフォルトのreduce()が呼ばれます。
 以下のように、コメントには identity function と書かれています。

 /**
   * This method is called once for each key. Most applications will define
   * their reduce class by overriding this method. The default implementation
   * is an identity function.
   */
  @SuppressWarnings("unchecked")
  protected void reduce(KEYIN key, Iterable<VALUEIN> values, Context context
                        ) throws IOException, InterruptedException {
    for(VALUEIN value: values) {
      context.write((KEYOUT) key, (VALUEOUT) value);
    }
  }

 old APIでは、org.apache.hadoop.mapred.JobConf.JavaのgetReducerClass()でデフォルトのクラスをIdentityReducer.classと設定しています。

   /**
   * Get the {@link Reducer} class for the job.
   * 
   * @return the {@link Reducer} class for the job.
   */
  public Class<? extends Reducer> getReducerClass() {
    return getClass("mapred.reducer.class",
                    IdentityReducer.class, Reducer.class);
  }

オープンソース万歳!(?)

MapReduceのメモ(デバッグ)

MapReduceのプログラムをデバッグする場合、ログを大量に出力したいことがあります。

このとき、静的にlog4jの設定を変える場合もありますが、手っ取り早く引数から
hadoop jar aaa.jar TestDriver \
-D mapred.map.child.log.level=TRACE \
-D mapred.reduce.child.log.level=TRACE \
input output
のように指定することもできます。(プログラムがToolRunnerを使用している場合のみです)

期待したログがでない場合はコードにデバッグメッセージを埋め込みましょう。(ただ、呼ばれる回数はデータサイズに依存することが多いので、ログでディスクが溢れないように注意して下さい)

MapReduceのメモ

型違い

MapReduceをJavaで記述する場合、通常

  1. ドライバー
  2. Mapper
  3. Reducer

の3点が必要になります。ドライバーで指定したキー/値の型と、Mapper/Reducerで指定した型が違う場合、以下のような例外を吐きます。ビルド時には検出できないので注意が必要です。

ドライバで指定したKeyがText型, ReducerはKeyがLongWritable型の場合のエクセプションのログ
(折り返しが変なので読みにくくて申し訳ないです。。)

java.io.IOException: wrong key class: org.apache.hadoop.io.LongWritable is not class org.apache.hadoop.io.Text

[完全なログ]
https://gist.github.com/kawamon/82b46959927ac1361a68#file-mapreduce-exception

JobTracker HA

本日 CDH4.2 がリリースされました(リリースノート)が、その中の目玉機能としてあげられるのが
JobTracker HA
でしょう。

従来 Hadoop には、下記の SPOF (単一障害点)があると言われていました。
1. NameNode
2. JobTracker

1.に関しては、昨年NameNode HAが公開され解決していたのですが、今回のリリースで2.も実現されたことになります。
JobTracker HAはNameNode HAと同様にActive-Standby構成をとり、QJMやZKFCを利用しています。

詳細は下記リンクを参照して下さい。
https://ccp.cloudera.com/display/CDH4DOC/Configuring+High+Availability+for+the+JobTracker+%28MRv1%29

JobTrackerはNameNodeのようなメタ情報を持たないため、最悪障害発生時時にはJobTrackerを再起動してジョブを投入できたのですが、数時間かかるジョブのやりなおしは避けたいものです。このような機能が必要に応じて選択できるのは喜ばしいですね。