部分參考:http://www.javaeye.com/topic/606962
1.圖解MapReduce
MapReduce整體流程圖
並行讀取文本中的內容,然後進行MapReduce操作
Map過程:並行讀取三行,對讀取的單詞進行map操作,每個詞都以<key,value>形式產生
reduce操作是對map的結果進行排序,合并,最後得出詞頻。
2.簡單過程:
Input:
Hello World Bye World
Hello Hadoop Bye Hadoop
Bye Hadoop Hello Hadoop
Map:
<Hello,1>
<World,1>
<Bye,1>
<World,1>
<Hello,1>
<Hadoop,1>
<Bye,1>
<Hadoop,1>
<Bye,1>
<Hadoop,1>
<Hello,1>
<Hadoop,1>
Sort:
<Bye,1>
<Bye,1>
<Bye,1>
<Hadoop,1>
<Hadoop,1>
<Hadoop,1>
<Hadoop,1>
<Hello,1>
<Hello,1>
<Hello,1>
<World,1>
<World,1>
Combine:
<Bye,1,1,1>
<Hadoop,1,1,1,1>
<Hello,1,1,1>
<World,1,1>
Reduce:
<Bye,3>
<Hadoop,4>
<Hello,3>
<World,2>
MergeSort的過程(ps:2012-10-18)
Map:
<Hello,1><World,1><Bye,1><World,1><Hello,1><Hadoop,1><Bye,1><Hadoop,1><Bye,1><Hadoop,1><Hello,1><Hadoop,1>
MergeSort:
- <Hello,1><World,1><Bye,1><World,1><Hello,1><Hadoop,1> | <Bye,1><Hadoop,1><Bye,1><Hadoop,1><Hello,1><Hadoop,1>
- <Hello,1><World,1><Bye,1> || <World,1><Hello,1><Hadoop,1> | <Bye,1><Hadoop,1><Bye,1> || <Hadoop,1><Hello,1><Hadoop,1>
- <Hello,1><World,1> ||| <Bye,1> || <World,1><Hello,1> ||| <Hadoop,1> | <Bye,1><Hadoop,1> ||| <Bye,1> || <Hadoop,1><Hello,1> ||| <Hadoop,1>
- MergeArray結果:<Hello,1><World,1> ||| <Bye,1> || <Hello,1><World,1> ||| <Hadoop,1> | <Bye,1><Hadoop,1> ||| <Bye,1> || <Hadoop,1><Hello,1> ||| <Hadoop,1> 在|||這一層級
- MergeArray結果:<Bye,1><Hello,1><World,1> || <Hadoop,1><Hello,1><World,1> | <Bye,1><Bye,1><Hadoop,1> || <Hadoop,1><Hadoop,1><Hello,1> 在||這一層級
- MergeArray結果:<Bye,1><Hadoop,1><Hello,1><World,1><Hello,1><World,1> | <Bye,1><Bye,1><Hadoop,1><Hadoop,1><Hello,1><Hadoop,1> 在|這一層級
- MergeArray結果:<Bye,1><Bye,1><Bye,1><Hadoop,1><Hadoop,1><Hadoop,1><Hadoop,1><Hello,1><Hello,1><Hello,1><World,1><World,1> 排序完成
3.代碼執行個體:View Code
package com.felix;import java.io.IOException;import java.util.Iterator;import java.util.StringTokenizer;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapred.FileInputFormat;import org.apache.hadoop.mapred.FileOutputFormat;import org.apache.hadoop.mapred.JobClient;import org.apache.hadoop.mapred.JobConf;import org.apache.hadoop.mapred.MapReduceBase;import org.apache.hadoop.mapred.Mapper;import org.apache.hadoop.mapred.OutputCollector;import org.apache.hadoop.mapred.Reducer;import org.apache.hadoop.mapred.Reporter;import org.apache.hadoop.mapred.TextInputFormat;import org.apache.hadoop.mapred.TextOutputFormat;/** * * 描述:WordCount explains by Felix * @author Hadoop Dev Group */public class WordCount{ /** * MapReduceBase類:實現了Mapper和Reducer介面的基類(其中的方法只是實現介面,而未作任何事情) * Mapper介面: * WritableComparable介面:實現WritableComparable的類可以相互比較。所有被用作key的類應該實現此介面。 * Reporter 則可用於報告整個應用的運行進度,本例中未使用。 * */ public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> { /** * LongWritable, IntWritable, Text 均是 Hadoop 中實現的用於封裝 Java 資料類型的類,這些類實現了WritableComparable介面, * 都能夠被序列化從而便於在分布式環境中進行資料交換,你可以將它們分別視為long,int,String 的替代品。 */ private final static IntWritable one = new IntWritable(1); private Text word = new Text(); /** * Mapper介面中的map方法: * void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter) * 映射一個單個的輸入k/v對到一個中間的k/v對 * 輸出對不需要和輸入對是相同的類型,輸入對可以映射到0個或多個輸出對。 * OutputCollector介面:收集Mapper和Reducer輸出的<k,v>對。 * OutputCollector介面的collect(k, v)方法:增加一個(k,v)對到output */ public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); output.collect(word, one); } } } public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { int sum = 0; while (values.hasNext()) { sum += values.next().get(); } output.collect(key, new IntWritable(sum)); } } public static void main(String[] args) throws Exception { /** * JobConf:map/reduce的job配置類,向hadoop架構描述map-reduce執行的工作 * 構造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等 */ JobConf conf = new JobConf(WordCount.class); conf.setJobName("wordcount"); //設定一個使用者定義的job名稱 conf.setOutputKeyClass(Text.class); //為job的輸出資料設定Key類 conf.setOutputValueClass(IntWritable.class); //為job輸出設定value類 conf.setMapperClass(Map.class); //為job設定Mapper類 conf.setCombinerClass(Reduce.class); //為job設定Combiner類 conf.setReducerClass(Reduce.class); //為job設定Reduce類 conf.setInputFormat(TextInputFormat.class); //為map-reduce任務設定InputFormat實作類別 conf.setOutputFormat(TextOutputFormat.class); //為map-reduce任務設定OutputFormat實作類別 /** * InputFormat描述map-reduce中對job的輸入定義 * setInputPaths():為map-reduce job設定路徑數組作為輸入列表 * setInputPath():為map-reduce job設定路徑數組作為輸出資料行表 */ FileInputFormat.setInputPaths(conf, new Path(args[0])); FileOutputFormat.setOutputPath(conf, new Path(args[1])); JobClient.runJob(conf); //運行一個job }}