コンバイナーは、ローカル マップ タスクで動作するレデューサーのようなものであるという印象を受けました。つまり、出力転送のネットワーク帯域幅を削減するために、個々のマップ タスクの結果を集約します。
そして、読んでみるHadoop- The definitive guide 3rd edition
と、私の理解は正しいようです。
第2章(34ページ)より
コンバイナー関数 多くの MapReduce ジョブは、クラスターで使用できる帯域幅によって制限されるため、マップ タスクとリデュース タスク間で転送されるデータを最小限に抑えることが重要です。Hadoop を使用すると、マップ出力で実行するコンバイナ関数を指定できます。コンバイナ関数の出力は、reduce 関数への入力を形成します。コンバイナ関数は最適化であるため、Hadoop は特定のマップ出力レコードに対して何回呼び出すかを保証しません。つまり、コンバイナ関数を 0 回、1 回、または何度も呼び出すと、レデューサから同じ出力が生成されます。
そこで、単語数の問題について次のことを試しました。
job.setMapperClass(mapperClass);
job.setCombinerClass(reduceClass);
job.setNumReduceTasks(0);
カウンターは次のとおりです。
14/07/18 10:40:15 INFO mapred.JobClient: Counters: 10
14/07/18 10:40:15 INFO mapred.JobClient: File System Counters
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of bytes read=293
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of bytes written=75964
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of read operations=0
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of large read operations=0
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of write operations=0
14/07/18 10:40:15 INFO mapred.JobClient: Map-Reduce Framework
14/07/18 10:40:15 INFO mapred.JobClient: Map input records=7
14/07/18 10:40:15 INFO mapred.JobClient: Map output records=16
14/07/18 10:40:15 INFO mapred.JobClient: Input split bytes=125
14/07/18 10:40:15 INFO mapred.JobClient: Spilled Records=0
14/07/18 10:40:15 INFO mapred.JobClient: Total committed heap usage (bytes)=85000192
そしてここにありますpart-m-00000
:
hello 1
world 1
Hadoop 1
programming 1
mapreduce 1
wordcount 1
lets 1
see 1
if 1
this 1
works 1
12345678 1
hello 1
world 1
mapreduce 1
wordcount 1
したがって、明らかにコンバイナーは適用されません。Hadoop は、コンバイナーが呼び出されるかどうかをまったく保証しないことを理解しています。しかし、reduce フェーズをオンにすると、コンバイナーが呼び出されます。
この動作の理由
今、第 6 章 (208 ページ) を読んだときhow MapReduce works
。で説明されているこの段落を参照してくださいReduce side
。
map 出力が十分に小さい場合、reduce タスク JVM のメモリにコピーされます (バッファのサイズは、この目的に使用するヒープの割合を指定する mapred.job.shuffle.input.buffer.percent によって制御されます)。それ以外の場合は、ディスクにコピーされます。メモリ内バッファがしきい値サイズ (mapred.job.shuffle.merge.percent で制御) に達するか、マップ出力のしきい値数 (mapred.inmem.merge.threshold) に達すると、マージされてディスクにスピルされます。コンバイナーが指定されている場合、マージ中に実行され、ディスクに書き込まれるデータの量が削減されます。
この段落からの私の推論は次のとおりです。1)コンバイナーは削減フェーズでも実行されます。