【hadoop】Hadoop學習筆記(一)之示例程序:計算每年的最高溫度MaxTemperature

本《hadoop學習筆記》系列是在《hadoop: the definitive guide 3th》的基礎上通過網上額外蒐集資料和查看hadoop的API再加上自己的實踐方面的理解編寫而成的,主要針對hadoop的特性和功能學習以及Hadoop生態圈中的其他工具(如Pig,Hive,Hbase,Avro等等)。另外設計到hadoop編程方面的請查閱另一個筆記系列:《Hadoop編程筆記》。如果有同學同時也在研究這本書,歡迎溝通交流,在下能力有限,還望各路大神看到有不對的地方加以指正~~(本系列學習筆記還正在整理中,以後會陸續發佈)。

  本書第二章以一個很淺顯的例子爲大家提供了hadoop入門,那就是從氣象站中保存的歷史氣象信息裏面提取出每年的最高氣溫來。其大致過程如下(注意在不同階段的數據形式):

  

  注意:shuffle階段是把map的輸出傳輸到reduce任務的階段,其中包括了鍵值對的排序和分組。

  1.Map階段

  Map任務是十分簡單的,我們只需要從輸入文件中提取出年份和對應的溫度值即可,同時過濾掉壞的記錄。這裏我們選擇Text輸入格式(默認的),其中數據集的每一行作爲map任務輸入中的key-value pair中的value值,key值是對應行在輸入文件中的位移(以字節爲單位),但我們並不需要key的值,所以忽略之。下面我們來看一下map任務的java表示:

複製代碼
 1 import java.io.IOException;
 2 import org.apache.hadoop.io.IntWritable;
 3 import org.apache.hadoop.io.LongWritable;
 4 import org.apache.hadoop.io.Text;
 5 import org.apache.hadoop.mapreduce.Mapper;
 6 
 7 public class MaxTemperatureMapper
 8   extends Mapper<LongWritable, Text, Text, IntWritable> {  //注1
 9   private static final int MISSING = 9999;
10   @Override
11   public void map(LongWritable key, Text value, Context context)
12       throws IOException, InterruptedException {
13     String line = value.toString();
14     String year = line.substring(15, 19);
15     int airTemperature;
16     if (line.charAt(87) == '+') { // parseInt doesn't like leading plus signs
17       airTemperature = Integer.parseInt(line.substring(88, 92));
18     } else {
19       airTemperature = Integer.parseInt(line.substring(87, 92));
20     }
21     String quality = line.substring(92, 93);
22     if (airTemperature != MISSING && quality.matches("[01459]")) {
23       context.write(new Text(year), new IntWritable(airTemperature));
24     }
25   }
26 }
複製代碼

 注1:Mapper類是一個泛型,其中的四個類型參數(LongWritable, Text, Text, IntWritable)指明瞭Mapper任務的輸入(鍵,值)類型和輸出(鍵,值)類型。其中LongWritable相當於java中的long類型,類似的,Text~String,IntWritable~int,只不過前者在網絡傳輸時序列化操作方面做了優化。

  2. Reduce階段

  同樣的,Reducer類的四個類型參數也指明瞭Reducer任務的輸入(鍵,值)類型和輸出(鍵,值)類型。其輸入類型必須和Mapper任務的輸出類型匹配(在這個例子中爲(Text,IntWritable))。

複製代碼
 1 import java.io.IOException;
 2 import org.apache.hadoop.io.IntWritable;
 3 import org.apache.hadoop.io.Text;
 4 import org.apache.hadoop.mapreduce.Reducer;
 5 
 6 public class MaxTemperatureReducer
 7   extends Reducer<Text, IntWritable, Text, IntWritable> {
 8   @Override
 9   public void reduce(Text key, Iterable<IntWritable> values,
10       Context context)
11       throws IOException, InterruptedException {
12     int maxValue = Integer.MIN_VALUE;
13     for (IntWritable value : values) {
14       maxValue = Math.max(maxValue, value.get());
15     }
16     context.write(key, new IntWritable(maxValue));
17   }
18 }  
複製代碼

  3. 下面我們總體查看一下作業的運行代碼:

複製代碼
 1 import org.apache.hadoop.fs.Path;
 2 import org.apache.hadoop.io.IntWritable;
 3 import org.apache.hadoop.io.Text;
 4 import org.apache.hadoop.mapreduce.Job;
 5 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
 6 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
 7 
 8 public class MaxTemperature {
 9   public static void main(String[] args) throws Exception {
10     if (args.length != 2) {
11       System.err.println("Usage: MaxTemperature <input path> <output path>");
12       System.exit(-1);
13     }
14     Job job = new Job();
15     job.setJarByClass(MaxTemperature.class);
16     job.setJobName("Max temperature");
17 
18     FileInputFormat.addInputPath(job, new Path(args[0]));
19     FileOutputFormat.setOutputPath(job, new Path(args[1]));
20 
21     job.setMapperClass(MaxTemperatureMapper.class);
22     job.setReducerClass(MaxTemperatureReducer.class);
23 
24     job.setOutputKeyClass(Text.class);              //注1
25     job.setOutputValueClass(IntWritable.class);
26 
27     System.exit(job.waitForCompletion(true) ? 0 : 1);
28   }
29 }
複製代碼

 注1:setOutputKeyClass()和setOutputValueClass()控制map任務和reduce任務的輸出(兩者輸出類型相同的情況下),如果他們不一樣,那麼map的輸出就要通過setMapOutputKeyClass()和setMapOutputValueClass()來設定了(reduce任務的輸出設定之手前兩者的影響)。

 附1:map的輸入格式由Job的靜態方法 public void setInputFormatClass(Class<? extends InputFormat> cls)來設定,默認爲TextInputFormat(在本例中並未顯式給出)。

 

 通過以下命令來運行我們的第一個hadoop程序:
% export HADOOP_CLASSPATH=hadoop-examples.jar    //HADOOP_CLASSPATH的具體含義請參看這裏
% hadoop MaxTemperature input/ncdc/sample.txt output

   其中sample.txt是我們指定的本地輸入文件,output是我們指定的輸出文件所在目錄,注意此目錄在運行前不應該存在,否則程序會報錯並停止運行,這樣做的目的主要是爲了防止被指定的目錄如果是另一個已存在的包含大量珍貴數據的目錄,那麼此目錄下的文件就會被覆蓋掉從而造成數據損壞。
  運行成功後就會在output目錄下產生part-r-00000文件和_SUCCESS文件,前者對應於reduce任務的輸出,每個reducer對應於一個這樣的輸出文件,以零(00000)開始計數(通過特殊的設置,reducer也可以產生多個輸出文件,這個我們在後面再介紹);後者是一個內容爲空的標誌文件(marker),表示作業已經成功完成。

轉載請註明出處:http://www.cnblogs.com/beanmoon/archive/2012/12/07/2804183.html

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