MapReduce可以分为两个阶段来处理,一个阶段为map,另一个阶段为reduce.每个阶段都有键值对的输入和输出参数,输入输出键值对的类型由程序决定,程序同样指定了两个函数,map函数和reduce函数。

1.编写Mapper程序

  1. package com.rickywag.hadoop;  
  2.   
  3. import org.apache.hadoop.io.IntWritable;  
  4. import org.apache.hadoop.io.LongWritable;  
  5. import org.apache.hadoop.io.Text;  
  6. import org.apache.hadoop.mapreduce.Mapper;  
  7. import java.io.IOException;  
  8.   
  9.   
  10. /** 
  11.  * Mapper程序主要用于处理数据,过滤不需要的数据,把需要的程序输出到reduce程序。 
  12.  *  @author Ricky 
  13.  *  @since 2014/08/25 
  14.  */  
  15. public class MaxTemperatureMapper  
  16.         extends Mapper<LongWritable, Text, Text, IntWritable> {  
  17.     private static final int MISSING = 9999;  
  18.   
  19.     /** 
  20.      * map函数主要用于解析NCDC文件中每一行的年份和气温 
  21.      * @param key NCDC文件中信息行数的偏移量 
  22.      * @param value NCDC文件对应行数偏移量的信息 
  23.      * @param context 输出变量 
  24.      * @throws IOException IO异常 
  25.      * @throws InterruptedException 线程中断异常 
  26.      */  
  27.     @Override  
  28.     public void map(LongWritable key, Text value, Context context)  
  29.             throws IOException, InterruptedException {  
  30.         String line = value.toString(); //获取每一行NCDC信息  
  31.         String year = line.substring(15, 19);//获取每一行的年份  
  32.         //获取每一行的温度  
  33.         int airTemperature;  
  34.         if (line.charAt(87) == '+') { //解析int字符串不需要‘+’  
  35.             airTemperature = Integer.parseInt(line.substring(88, 92));  
  36.         } else {  
  37.             airTemperature = Integer.parseInt(line.substring(87, 92));  
  38.         }  
  39.         String quality = line.substring(92, 93);  
  40.         if (airTemperature != MISSING && quality.matches("[01459]")) {  
  41.             //输出年份,温度到reduce阶段,在输出到reduce之前,mapper会对数据进行排序和分组。  
  42.             context.write(new Text(year), new IntWritable(airTemperature));  
  43.         }  
  44.     }  
  45. }  

2.编写Reducer程序

  1. package com.rickywag.hadoop;  
  2.   
  3. import org.apache.hadoop.io.IntWritable;  
  4. import org.apache.hadoop.io.Text;  
  5. import org.apache.hadoop.mapreduce.Reducer;  
  6.   
  7. import java.io.IOException;  
  8.   
  9. /** 
  10.  * 找出一年中最高的温度 
  11.  *  @author Ricky 
  12.  *  @since 2014/08/25 
  13.  */  
  14. public class MaxTemperatureReducer  
  15.         extends Reducer<Text, IntWritable, Text, IntWritable> {  
  16.   
  17.     /** 
  18.      * 通过map处理过的数据,找出一年中的最高温度 
  19.      * @param key 年份 
  20.      * @param values 该年份的所有温度 
  21.      * @param context 把结果输出到下一个阶段 
  22.      * @throws IOException IO异常 
  23.      * @throws InterruptedException 线程中断异常 
  24.      */  
  25.     @Override  
  26.     public void reduce(Text key, Iterable<IntWritable> values,  
  27.                        Context context)  
  28.             throws IOException, InterruptedException {  
  29.         int maxValue = Integer.MIN_VALUE;//int 类型数据的最小值  
  30.         //找出一年中的最高气温  
  31.         for (IntWritable value : values) {  
  32.             maxValue = Math.max(maxValue, value.get());  
  33.         }  
  34.         //把最高温度的年份作为key,最高的温度作为值,输出到文件中。  
  35.         context.write(key, new IntWritable(maxValue));  
  36.     }  
  37. }  

这是整个MapReduce的流程
mapreduce

3.编写Job Object

  1. package com.rickywag.hadoop;  
  2.   
  3. import org.apache.hadoop.fs.Path;  
  4. import org.apache.hadoop.io.IntWritable;  
  5. import org.apache.hadoop.io.Text;  
  6. import org.apache.hadoop.mapreduce.Job;  
  7. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  8. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  9.   
  10. /** 
  11.  *  控制求最大温度作业的执行 
  12.  *  @author Ricky 
  13.  *  @since 2014/08/25 
  14.  */  
  15. public class MaxTemperature {  
  16.     public static void main(String[] args) throws Exception {  
  17.         /** 
  18.          * input path : NCDC数据文件在HDFS中的位置  
  19.          * output path: MapReduce处理完成后结果存放的位置(默认该路径在HDFS中不存在,若已经存在会抛异常) 
  20.          */  
  21.         if (args.length != 2) {  
  22.             System.err.println("Usage: MaxTemperature <input path> <output path>");  
  23.             System.exit(-1);  
  24.         }  
  25.         Job job = new Job();  
  26.         job.setJarByClass(MaxTemperature.class);//job会查询包涵该类的包。  
  27.         job.setJobName("Max temperature");//设置作业名称  
  28.         FileInputFormat.addInputPath(job, new Path(args[0]));//设置NCDC文件在HDFS存在的位置  
  29.         FileOutputFormat.setOutputPath(job, new Path(args[1]));//设置job运行结果存放的位置  
  30.         job.setMapperClass(MaxTemperatureMapper.class);//设置map阶段执行的代码  
  31.         job.setReducerClass(MaxTemperatureReducer.class);//设置reduce阶段执行的代码  
  32.         job.setOutputKeyClass(Text.class);//设置输出key  
  33.         job.setOutputValueClass(IntWritable.class);//设置输出的值  
  34.         System.exit(job.waitForCompletion(true) ? 0 : 1);//若作业正常执行完成,系统正常退出。  
  35.     }  
  36. }  

转载地址:http://www.rickywag.com/358.html