第2章 关于MapReduce
使用Hadoop来分析数据
-
1.查找最高气温的Mapper类
// cc MaxTemperatureMapper Mapper for maximum temperature example // vv MaxTemperatureMapper import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; public class MaxTemperatureMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private static final int MISSING = 9999; @Override 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)); } } } // ^^ MaxTemperatureMapper- 代码解析
-
① Mapper类 : Mapper类是一个泛型参数,有四个参数类型,分别指定map函数的输入键、输入值、输出键和输出值。本例 输入键是一个长整数偏移量,输入值是一行文本,输出键是年份,输出值是气温。
-
② map()函数 : map()方法的输入是一个键 和 一个值。本例首先将包含一行输入的Text转换为Java的String类型。之后用subString()方法提取有用列。
map()方法提供Context实例,用于将数据写入输出记录中。
-
- 代码解析
-
2.查找最高气温的Reducer类
// cc MaxTemperatureReducer Reducer for maximum temperature example // vv MaxTemperatureReducer import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; public class MaxTemperatureReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int maxValue = Integer.MIN_VALUE; //获取每个key(year)对应的最大值(气温) for (IntWritable value : values) { maxValue = Math.max(maxValue, value.get()); } //将数据写出 输出类型和Reducer类输出类型一致 context.write(key, new IntWritable(maxValue)); } } // ^^ MaxTemperatureReducer- 代码解析
- ①Reducer类:Reducer类也有四个形参类型,用于指定输入和输出的类型。Reducer的输入类型必须和Mapper的输出类型匹配。
- ②reduce()函数:reduce()函数输出类型 要和 Reducer的输出类型匹配
- 代码解析
-
3.启动应用程序找出最高气温(dirver)
// cc MaxTemperature Application to find the maximum temperature in the weather dataset // vv MaxTemperature import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class MaxTemperature { public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Usage: MaxTemperature <input path> <output path>"); System.exit(-1); } //①创建Job对象,指定作业执行规范。 Job job = new Job(); //②指定应用程序类名,hadoop通过类名找到该jar包。 job.setJarByClass(MaxTemperature.class); //设置job名 job.setJobName("Max temperature"); //③指定输入和输出数据的路径。 FileInputFormat.addInputPath(job, new Path(args[0])); //运行作业前该输出目录不应该存在。 FileOutputFormat.setOutputPath(job, new Path(args[1])); //④指定Mapper和Reducer类 job.setMapperClass(MaxTemperatureMapper.class); //job.setCombinerClass(MaxTemperatureReducer.class);//如果需要开始combiner job.setReducerClass(MaxTemperatureReducer.class); //⑤指定reduce输出的类型。 //默认情况map的输出类型和reduce相同,如果不同需要单独设置map的输出类型。 job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); //⑥调用waitForCompletion()提交作业并等待执行完成 System.exit(job.waitForCompletion(true) ? 0 : 1); } } // ^^ MaxTemperature -
4 combiner函数
- ①Hadoop允许用户针对map任务的输出指定一个combiner,combiner函数的输出作为reduce函数的输入。combiner能够减少mapper 和 reducer之间的数据量。相当于map端的reduce函数,提前做一次reduce预聚合。
- ② combiner属于优化方案,不是必选的。使用combiner函数一定不影响计算结果。比如求温度的平均值就不能使用combiner函数。因为 mean(0,20,25,15) = 14,而 mean(mean(0,20),mean(25,15))=15。
- ③ cominer不能代替reduce函数,combiner只是对单个map进行处理。最后仍然需要reducer函数处理不同map输出中具有相同key的记录。
- ④程序中如何指定combiner。combiner函数实现和reducer的逻辑一样的。所以只需在应用程序中添加如下代码:
job.setCombinerClass(MaxTemperatureReducer.class)
3698



被折叠的 条评论
为什么被折叠?



