Hadoop示例程序WordCount運行及詳解


最近在學習雲計算,研究Haddop框架,費了一整天時間將Hadoop在Linux下完全運行起來,看到官方的map-reduce的demo程序WordCount,仔細研究了一下,算做入門了。


運行方法:

假設:

  • /home/cq/wordcount/input - 是 HDFS 中的輸入路徑

  • /home/cq/wordcount/output - 是 HDFS 中的輸出路徑

用示例文本文件做爲輸入:

$ bin/hadoop fs -ls /home/cq/wordcount/input/
/home/cq /wordcount/input/file01
/home/cq /wordcount/input/file02

$ bin/hadoop fs -cat /home/cq/wordcount/input/file01
Hello World Bye World

$ bin/hadoop dfs -cat /home/cq/wordcount/input/file02
Hello Hadoop Goodbye Hadoop


運行應用程序:

$ bin/hadoop jar /*/WordCount  /home/cq/wordcount/input /home/cq/wordcount/output

輸出是:

$ bin/hadoop dfs -cat /home/cq/wordcount/output/part-00000
Bye 1
Goodbye 1
Hadoop 2
Hello 2
World 2




詳解:

   其實WordCount並不難,只是一下子接觸到了很多的API,有一些陌生,還有就是很傳統的開發相比,map-reduce確實是一種新的編程理 念,爲了讓各位新手少走彎路,我將WordCount中的很多API都做了註釋,其實這些方法搞明白了以後程序就很簡單了,無非就是將一句話分詞,先用 map處理再用reduce處理,最後再main函數中設置一些信息,然後run(),程序就結束了。好了,不廢話,直接上代碼:



Java代碼
  1. package  com.felix;  


  2. import  java.io.IOException;  

  3. import  java.util.Iterator;  

  4. import  java.util.StringTokenizer;  


  5. import  org.apache.hadoop.fs.Path;  

  6. import  org.apache.hadoop.io.IntWritable;  

  7. import  org.apache.hadoop.io.LongWritable;  

  8. import  org.apache.hadoop.io.Text;  

  9. import  org.apache.hadoop.mapred.FileInputFormat;  

  10. import  org.apache.hadoop.mapred.FileOutputFormat;  

  11. import  org.apache.hadoop.mapred.JobClient;  

  12. import  org.apache.hadoop.mapred.JobConf;  

  13. import  org.apache.hadoop.mapred.MapReduceBase;  

  14. import  org.apache.hadoop.mapred.Mapper;  

  15. import  org.apache.hadoop.mapred.OutputCollector;  

  16. import  org.apache.hadoop.mapred.Reducer;  

  17. import  org.apache.hadoop.mapred.Reporter;  

  18. import  org.apache.hadoop.mapred.TextInputFormat;  

  19. import  org.apache.hadoop.mapred.TextOutputFormat;  

  20. /**

  21. *

  22. * 描述:WordCount explains by Felix

  23. * @author Hadoop Dev Group

  24. */

  25. publicclass  WordCount  

  26. {  


  27. /**

  28.     * MapReduceBase類:實現了Mapper和Reducer接口的基類(其中的方法只是實現接口,而未作任何事情)

  29.     * Mapper接口:

  30.     * WritableComparable接口:實現WritableComparable的類可以相互比較。所有被用作key的類應該實現此接口。

  31.     * Reporter 則可用於報告整個應用的運行進度,本例中未使用。

  32.     *

  33.     */

  34. publicstaticclass  Map  extends  MapReduceBase  implements

  35.            Mapper<LongWritable, Text, Text, IntWritable>  

  36.    {  

  37. /**

  38.         * LongWritable, IntWritable, Text 均是 Hadoop 中實現的用於封裝 Java 數據類型的類,這些類實現了WritableComparable接口,

  39.         * 都能夠被串行化從而便於在分佈式環境中進行數據交換,你可以將它們分別視爲long,int,String 的替代品。

  40.         */

  41. privatefinalstatic  IntWritable one =  new  IntWritable( 1 );  

  42. private  Text word =  new  Text();  


  43. /**

  44.         * Mapper接口中的map方法:

  45.         * void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter)

  46.         * 映射一個單個的輸入k/v對到一箇中間的k/v對

  47.         * 輸出對不需要和輸入對是相同的類型,輸入對可以映射到0個或多個輸出對。

  48.         * OutputCollector接口:收集Mapper和Reducer輸出的<k,v>對。

  49.         * OutputCollector接口的collect(k, v)方法:增加一個(k,v)對到output

  50.         */

  51. publicvoid  map(LongWritable key, Text value,  

  52.                OutputCollector<Text, IntWritable> output, Reporter reporter)  

  53. throws  IOException  

  54.        {  

  55.            String line = value.toString();  

  56.            StringTokenizer tokenizer = new  StringTokenizer(line);  

  57. while  (tokenizer.hasMoreTokens())  

  58.            {  

  59.                word.set(tokenizer.nextToken());  

  60.                output.collect(word, one);  

  61.            }  

  62.        }  

  63.    }  


  64. publicstaticclass  Reduce  extends  MapReduceBase  implements

  65.            Reducer<Text, IntWritable, Text, IntWritable>  

  66.    {  

  67. publicvoid  reduce(Text key, Iterator<IntWritable> values,  

  68.                OutputCollector<Text, IntWritable> output, Reporter reporter)  

  69. throws  IOException  

  70.        {  

  71. int  sum =  0 ;  

  72. while  (values.hasNext())  

  73.            {  

  74.                sum += values.next().get();  

  75.            }  

  76.            output.collect(key, new  IntWritable(sum));  

  77.        }  

  78.    }  


  79. publicstaticvoid  main(String[] args)  throws  Exception  

  80.    {  

  81. /**

  82.         * JobConf:map/reduce的job配置類,向hadoop框架描述map-reduce執行的工作

  83.         * 構造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等

  84.         */

  85.        JobConf conf = new  JobConf(WordCount. class );  

  86.        conf.setJobName("wordcount" );            //設置一個用戶定義的job名稱


  87.        conf.setOutputKeyClass(Text.class );     //爲job的輸出數據設置Key類

  88.        conf.setOutputValueClass(IntWritable.class );    //爲job輸出設置value類


  89.        conf.setMapperClass(Map.class );          //爲job設置Mapper類

  90.        conf.setCombinerClass(Reduce.class );       //爲job設置Combiner類

  91.        conf.setReducerClass(Reduce.class );         //爲job設置Reduce類


  92.        conf.setInputFormat(TextInputFormat.class );     //爲map-reduce任務設置InputFormat實現類

  93.        conf.setOutputFormat(TextOutputFormat.class );   //爲map-reduce任務設置OutputFormat實現類


  94. /**

  95.         * InputFormat描述map-reduce中對job的輸入定義

  96.         * setInputPaths():爲map-reduce job設置路徑數組作爲輸入列表

  97.         * setInputPath():爲map-reduce job設置路徑數組作爲輸出列表

  98.         */

  99.        FileInputFormat.setInputPaths(conf, new  Path(args[ 0 ]));  

  100.        FileOutputFormat.setOutputPath(conf, new  Path(args[ 1 ]));  


  101.        JobClient.runJob(conf);         //運行一個job

轉載自http://hi.baidu.com/whyang2006/item/436a720c4e15a013addc70c4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章