【转】Hadoop MapReduce新旧API区别

 

FROM : http://blog.csdn.net/jokes000/article/details/7060475

 

新增的Java MapReduce API

Hadoop的版本0.20.0包含有一个新的 Java MapReduce API,有时也称为"上下文对象"(context object),旨在使API在今后更容易扩展。新的API 在类型上不兼容先前的API,所以,需要重写以前的应用程序才能使新的API发挥作用。

新增的API 和旧的API 之间,有下面几个明显的区别。

新的API 倾向于使用虚类,而不是接口,因为这更容易扩展。例如,可以无需修改类的实现而在虚类中添加一个方法(即用默认的实现)。在新的API 中, mapper 和reducer现在都是虚类。

新的API 放在org.apache.hadoop.mapreduce 包(和子包)中。之前版本的API 依旧放在org.apache.hadoop.mapred中。

新的API充分使用上下文对象,使用户代码能与MapReduce系统通信。例如,MapContext 基本具备了JobConf、OutputCollector和Reporter的功能。

新的API 同时支持"推"(push)和"拉"(pull)式的迭代。这两类API,均可以将键/值对记录推给mapper,但除此之外,新的API 也允许把记录从map()方法中拉出。对reducer来说是一样的。"拉"式处理数据的好处是可以实现数据的批量处理,而非逐条记录地处理。

新增的API实现了配置的统一。旧API 通过一个特殊的JobConf 对象配置作业,该对象是Hadoop配置对象的一个扩展 (用于配置守护进程,详情请参见第130页的"API配置"小节)。在新的API 中,我们丢弃这种区分,所有作业的配置均通过Configuration 来完成。

新API中作业控制由Job类实现,而非JobClient类,新API中删除了JobClient类。

输出文件的命名方式稍有不同。map的输出文件名为part-m-nnnnn,而reduce的输出为part-r-nnnnn(其中nnnnn表示分块序号,为整数,且从0开始算)。

例2-6 显示了使用新API 重写的MaxTemperature应用。不同之处已加粗显示。

将旧API写的Mapper和Reducer类转换为新API时,记住将map()和reduce()的签名转换为新形式。如果只是将类的继承修改为对新的Mapper和Reducer类的继承,编译的时候也不会报错或显示警告信息,因为新的Mapper和Reducer类同样也提供了等价的map()和reduce()函数。但是,自己写的mapper或reducer代码是不会被调用的,这会导致难以诊断的错误。

例2-6. 用新上下文对象MapReduce API重写的MaxTemperature应用

 

  1. public class NewMaxTemperature {    
  2.    
  3.     static class NewMaxTemperatureMapper    
  4.         extends Mapper<LongWritable, Text, Text, IntWritable> {    
  5.    
  6.             private static final int MISSING = 9999;    
  7.             public void map(LongWritable key, Text value,Context context)    
  8.             throws IOException, InterruptedException {                 
  9.        
  10.                 String line = value.toString();           
  11.                 String year = line.substring(15, 19);           
  12.                 int airTemperature;           
  13.                   
  14.             if (line.charAt(87) == '+') { // parseInt doesn't like leading plus signs            
  15.                     airTemperature = Integer.parseInt(line.substring(88, 92));           
  16.                 } else {             
  17.                     airTemperature = Integer.parseInt(line.substring(87, 92));           
  18.             }           
  19.                   
  20.             String quality = line.substring(92, 93);    
  21.                 if (airTemperature != MISSING && quality.matches("[01459]")) {    
  22.                     context.write(new Text(year), new IntWritable(airTemperature));           
  23.                 }         
  24.         }       
  25.     }       
  26.      
  27.     static class NewMaxTemperatureReducer    
  28.             extends Reducer<Text, IntWritable, Text, IntWritable> {           
  29.           
  30.         public void reduce(Text key, Iterable<IntWritable> values, Context context)             
  31.                 throws IOException, InterruptedException {                 
  32.    
  33.                 int maxValue = Integer.MIN_VALUE;           
  34.                 for (IntWritable value : values) {             
  35.                 maxValue = Math.max(maxValue, value.get());           
  36.                 }           
  37.                 context.write(key, new IntWritable(maxValue));         
  38.             }       
  39.     }    
  40.    
  41.     public static void main(String[] args) throws Exception {         
  42.         if (args.length != 2) {           
  43.             System.err.println("Usage: NewMaxTemperature  
  44.             <input path> <output path>");       
  45.             System.exit(-1);    
  46.         }             
  47.   
  48.         Job job = new Job();         
  49.         job.setJarByClass(NewMaxTemperature.class);    
  50.   
  51.         FileInputFormat.addInputPath(job, new Path(args[0]));    
  52.         FileOutputFormat.setOutputPath(job, new Path(args[1]));             
  53.   
  54.         job.setMapperClass(NewMaxTemperatureMapper.class);         
  55.         job.setReducerClass(NewMaxTemperatureReducer.class);    
  56.         job.setOutputKeyClass(Text.class);    
  57.         job.setOutputValueClass(IntWritable.class);             
  58.   
  59.         System.exit(job.waitForCompletion(true) ? 0 : 1);       
  60.     }    
  61.     }    
public class NewMaxTemperature {  
 
	static class NewMaxTemperatureMapper  
		extends Mapper<LongWritable, Text, Text, IntWritable> {  
 
	    	private static final int MISSING = 9999;  
	    	public void map(LongWritable key, Text value,Context context)  
			throws IOException, InterruptedException {               
	 
	    		String line = value.toString();         
	    		String year = line.substring(15, 19);         
	    		int airTemperature;         
	    		
			if (line.charAt(87) == '+') { // parseInt doesn't like leading plus signs          
	      			airTemperature = Integer.parseInt(line.substring(88, 92));         
	    		} else {           
	      			airTemperature = Integer.parseInt(line.substring(87, 92));         
		   	}         
		    	
			String quality = line.substring(92, 93);  
		    	if (airTemperature != MISSING && quality.matches("[01459]")) {  
		      		context.write(new Text(year), new IntWritable(airTemperature));         
		    	}       
	  	}     
	}     
   
  	static class NewMaxTemperatureReducer  
    		extends Reducer<Text, IntWritable, Text, IntWritable> {         
    	
		public void reduce(Text key, Iterable<IntWritable> values, Context context)           
        		throws IOException, InterruptedException {               
 
		      	int maxValue = Integer.MIN_VALUE;         
		      	for (IntWritable value : values) {           
				maxValue = Math.max(maxValue, value.get());         
		      	}         
		      	context.write(key, new IntWritable(maxValue));       
    		}     
  	}  
 
	public static void main(String[] args) throws Exception {       
		if (args.length != 2) {         
			System.err.println("Usage: NewMaxTemperature
			<input path> <output path>");     
			System.exit(-1);  
		}           

		Job job = new Job();       
		job.setJarByClass(NewMaxTemperature.class);  

		FileInputFormat.addInputPath(job, new Path(args[0]));  
		FileOutputFormat.setOutputPath(job, new Path(args[1]));           

		job.setMapperClass(NewMaxTemperatureMapper.class);       
		job.setReducerClass(NewMaxTemperatureReducer.class);  
		job.setOutputKeyClass(Text.class);  
		job.setOutputValueClass(IntWritable.class);           

		System.exit(job.waitForCompletion(true) ? 0 : 1);     
	}  
    }  

 

   原来MapReduce代码可在《Hadoop权威指南》内找到,大家可进行对比。

 

  又一例子:Hadoop in Action中第四章:

  

    1. package com;  
    2.   
    3. import java.io.IOException;  
    4. import org.apache.hadoop.conf.Configuration;  
    5. import org.apache.hadoop.conf.Configured;  
    6. import org.apache.hadoop.fs.Path;  
    7. import org.apache.hadoop.io.LongWritable;  
    8. import org.apache.hadoop.io.Text;  
    9. import org.apache.hadoop.mapreduce.Job;  
    10. import org.apache.hadoop.mapreduce.Mapper;  
    11. import org.apache.hadoop.mapreduce.Reducer;  
    12. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
    13. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;  
    14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
    15. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;  
    16. import org.apache.hadoop.util.Tool;                   
    17. import org.apache.hadoop.util.ToolRunner;  
    18.   
    19.   
    20. public class tt extends Configured implements Tool {  
    21.       
    22.     public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {  
    23.         public void map(LongWritable key, Text value, Context context)  
    24.             throws IOException, InterruptedException {  
    25.             //split的作用是将该字符串里面的变量赋值给citation这个字符串数组当中。  
    26.             String[] citation = value.toString().split(",");  
    27.             //使用新的API取代了collect相关的API,将map中的key和value进行了互换。  
    28.             context.write(new Text(citation[1]), new Text(citation[0]));    
    29.         }  
    30.     }  
    31.       
    32.     public static class Reduce extends Reducer<Text, Text, Text, Text> {  //前两个参数设置是输入参数,后两个参数是输出参数。  
    33.           
    34.         public void reduce(Text key, Iterable<Text> values, Context context)  
    35.             throws IOException, InterruptedException {  
    36.             String csv ="";  
    37.               
    38.             //Text类型是类似于String类型的文本格式,但是在处理编码上还是和String有差别,与内存序列化有关,是hadoop经过封装之后的新类。  
    39.             for (Text val:values) {  
    40.                 if (csv.length() > 0) csv += ",";  
    41.                 csv += val.toString();  
    42.             }  
    43.           
    44.             context.write(key, new Text(csv));  
    45.         }  
    46.     }  
    47.       
    48.     public int run(String[] args) throws Exception {  //由hadoop本身调用该程序  
    49.         Configuration conf = getConf();  
    50.         Job job = new Job(conf, "tt"); //利用job取代了jobclient  
    51.         job.setJarByClass(tt.class);  
    52.           
    53.         Path in = new Path(args[0]);  
    54.         Path out = new Path(args[1]);  
    55.         FileInputFormat.setInputPaths(job, in);  
    56.         FileOutputFormat.setOutputPath(job, out);  
    57.           
    58.         job.setMapperClass(MapClass.class);  
    59.         job.setReducerClass(Reduce.class);  
    60.         job.setInputFormatClass(TextInputFormat.class);  
    61.         job.setOutputFormatClass(TextOutputFormat.class);  
    62.         job.setOutputKeyClass(Text.class);  
    63.         job.setOutputValueClass(Text.class);  //此处如果不进行设置,系统会抛出异常,还要记住新旧API不能混用  
    64.           
    65.         System.exit(job.waitForCompletion(true)?0:1);  
    66.         return 0;  
    67.     }  
    68.       
    69.     public static void main(String[] args) throws Exception {  
    70.         int res = ToolRunner.run(new Configuration(), new tt(), args);    //调用新的类的方法免除配置的相关琐碎的细节  
    71.         System.exit(res);  
    72.     }  
    73. }  
posted @ 2015-07-06 09:52  MERRU  阅读(180)  评论(0)    收藏  举报