Hadoop セカンダリソートについて

象本にもちゃんと書いてあるが、まとめ。

例えば、以下のようなデータがあるとする。

A1 B11 C11
A1 B12 C12
A1 B13 C13
A2 B21 C21
A2 B22 C22
A2 B23 C23
A2 B24 C24

これを、カラムAの値毎にまとめてReducerで処理し、各Reducer呼び出し内ではカラムBの値順に処理したいとする。
言うなれば、カラムAは「処理単位カラム」、カラムBは「セカンダリソートカラム」とでも言えよう。

1.Sortフェーズのソート順として、A+Bを指定
→mapperのアウトプットのKeyクラスにはA、Bの値を保持する。
 必要に応じてソートのロジックを実装。
 Keyクラスの compareTo メソッド、
 もしくは、 Job#setSortComparatorClass (実体は"mapred.output.key.comparator.class")で指定したクラスの compare メソッドで実装
 

2.Reducerノードの決定を、Aに応じて行う
→Job#setPartitionerClass で指定したクラスの getPartition メソッドの実装

3.Reduce の実行単位の決定を、Aに応じて行う
→Job#setGroupingComparatorClass で指定したクラスの compare メソッドの実装

4.Reduce処理の中でBも使うなら、Valueクラスの中にBの値も入れておく(Key、Valueに二重持ちする)

4について
1〜3まで対応し、ValueクラスにBの値を保持していなければ、Reducerでは以下のようにデータを受け取ることになる。

■一回目の呼び出し
・Key
A1

・Value(B順にソート)
C11
C12
C13

■二回目の呼び出し
・Key
A2

・Value(B順にソート)
C21
C22
C23
C24

つまり、Bの値自体は捨てられてしまう・・・
ValueクラスにBの値も持てるようにすれば、こうなる。

■一回目の呼び出し
・Key
A1

・Value(B順にソート)
B11 C11
B12 C12
B13 C13

■二回目の呼び出し
・Key
A2

・Value(B順にソート)
B21 C21
B22 C22
B23 C23
B24 C24