S-JIS[2010-03-02/2010-03-19] 変更履歴

Hadoop Mapper

HadoopのMapperクラスについて。
チュートリアルではMapperのクラス名はMapだが、java.util.Mapと紛らわしいな(苦笑))

  • Hadoop APIドキュメントのMapper

Mapperの概要

Mapperは、入力をキーと値の組に分解(マッピング?)する。
Reducerは、このキー毎に値を演算(たいていは集計)する)

Mapperの出力は、Combinerが指定されていればCombinerに渡されることがある。
Reducerが指定されていれば、Reducerに渡される。
Reducerが0個であれば、直接OutputFormatに渡される。


Mapperの出力

チュートリアルでは、値の出力は以下の様にコーディングされている。

	public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
		private final static IntWritable one = new IntWritable(1);
		private Text word = new Text();

		@Override
		protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
			String line = value.toString();
			StringTokenizer tokenizer = new StringTokenizer(line);
			while (tokenizer.hasMoreTokens()) {
				word.set(tokenizer.nextToken());
				context.write(word, one);
			}
		}
	}

Strutsサーブレットプログラミングで“MTセーフ”に敏感になっている身としては、変数wordがフィールドに宣言されているのでマルチスレッドセーフになっていないのが気になる。
が、チュートリアルがこうなっているのだから、きっとMapperはマルチスレッドでは呼ばれないのだろう。


もうひとつ、context.write()wordインスタンスをそのまま渡しているのも気になる。
内部でインスタンスを保持していたら、word.set()を呼ぶと保持している値が変わってしまうから。

context.write()の中身は、Reducerの個数で異なる。
Reducerが1個以上の場合はMapTask.NewOutputCollectorのwrite()が呼ばれるが、シリアライズされる(wordのクラスであるTextのwrite()メソッドが呼ばれる)ので、インスタンスを直接保持するような事はしていないから大丈夫。

Reducerが0個の場合は直接OutputFormatに渡される。
TextOutputFormatではファイルストリームに出力しているので大丈夫。
TableOutputFormatではインスタンスのコピーを作って保持しているので大丈夫。


Mapperの種類

Mapper(Hadoop0.20.1)には以下のようなクラスがある。
自分でマッパーを作る際には、MapperTableMapper辺りを親クラスに使うのが普通だと思う。

クラス名 入力型 出力型 説明
KEYIN VALIN KEYOUT VALOUT
org.apache.hadoop.mapreduce.
Mapper
任意 任意 任意 任意 入力のキーと値をそのまま出力する。
チュートリアルサンプル
org.apache.hadoop.mapreduce.lib.map.
InverseMapper
任意 任意 VALIN KEYIN 入力のキーと値を入れ替えて出力する。
すなわち、出力キーは入力の値、出力値は入力のキーとなる。
org.apache.hadoop.mapreduce.lib.map.
TokenCounterMapper
Object
(未使用)
Text Text IntWritable 入力値をトークンに分割して、トークンをキー、「1」を値として出力する。
つまりはチュートリアルWordCountのMapと全く同じ。

HBase関連のMapper


Mapperの個数

実行時にいくつのMapper(MapTask)が作られるのかは、InputFormat#getSplits()によって決まる。[2010-03-19]
(getSplits()は、処理しやすい単位に入力を分割して、処理単位(処理範囲・InputSplit)のリストを返す)

TextInputFormatなら、ファイルの個数やファイルサイズに応じて分割してくれる。
HBaseTableInputFormatなら、テーブルのリージョン(領域)に応じて分割してくれる。

Reducerの個数


Hadoop APIへ戻る / Hadoop目次へ戻る / Java目次へ行く / 技術メモへ戻る
メールの送信先:ひしだま