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