MapReduce求最大值

一:背景

求最值是MapReduce的常见算法,应用也很广泛,比如说求出某大型销售网站各个站点销售量最大的商品,人口最多的城市等等,MapReduce求最大值的关键是要实现cleanUp()方法。

 

二:技术实现

#需求 有两个文件max和max2,现要求合并两个并找出最大值。

#max文件数据如下:

 

[java]  view plain  copy
 
  1. 10  
  2. 29  
  3. 50  
  4. 39  
  5. 88  
  6. 99  
  7. 29  
  8. 100  
  9.   
  10. 389  

#max2文件数据如下:

 

 

[java]  view plain  copy
 
  1. 10  
  2. 20  
  3. 39  
  4. 90  
  5. 33  
  6. 299  
  7.   
  8. 99  
  9. 390  
  10. 900  
  11. 999  
  12. 22  


实现代码如下:

 

 

[java]  view plain  copy
 
  1. public class MaxTest {  
  2.     // 定义输入路径  
  3.     private static final String INPUT_PATH = "hdfs://liaozhongmin:9000/max_file/*";  
  4.     // 定义输出路径  
  5.     private static final String OUT_PATH = "hdfs://liaozhongmin:9000/out";  
  6.   
  7.     public static void main(String[] args) {  
  8.   
  9.         try {  
  10.             // 创建配置信息  
  11.             Configuration conf = new Configuration();  
  12.   
  13.             // 创建文件系统  
  14.             FileSystem fileSystem = FileSystem.get(new URI(OUT_PATH), conf);  
  15.             // 如果输出目录存在,我们就删除  
  16.             if (fileSystem.exists(new Path(OUT_PATH))) {  
  17.                 fileSystem.delete(new Path(OUT_PATH), true);  
  18.             }  
  19.   
  20.             // 创建任务  
  21.             Job job = new Job(conf, MaxTest.class.getName());  
  22.   
  23.             //1.1 设置输入目录和设置输入数据格式化的类  
  24.             FileInputFormat.setInputPaths(job, INPUT_PATH);  
  25.             job.setInputFormatClass(TextInputFormat.class);  
  26.   
  27.             //1.2 设置自定义Mapper类和设置map函数输出数据的key和value的类型  
  28.             job.setMapperClass(MaxMapper.class);  
  29.             job.setMapOutputKeyClass(LongWritable.class);  
  30.             job.setMapOutputValueClass(NullWritable.class);  
  31.   
  32.             //1.3 设置分区和reduce数量(reduce的数量,和分区的数量对应,因为分区为一个,所以reduce的数量也是一个)  
  33.             job.setPartitionerClass(HashPartitioner.class);  
  34.             job.setNumReduceTasks(1);  
  35.   
  36.             //1.4 排序  
  37.             //1.5 归约  
  38.             //2.1 Shuffle把数据从Map端拷贝到Reduce端。  
  39.             //2.2 指定Reducer类和输出key和value的类型  
  40.             job.setReducerClass(MaxReducer.class);  
  41.             job.setOutputKeyClass(LongWritable.class);  
  42.             job.setOutputValueClass(NullWritable.class);  
  43.   
  44.             //2.3 指定输出的路径和设置输出的格式化类  
  45.             FileOutputFormat.setOutputPath(job, new Path(OUT_PATH));  
  46.             job.setOutputFormatClass(TextOutputFormat.class);  
  47.   
  48.             // 提交作业 退出  
  49.             System.exit(job.waitForCompletion(true) ? 0 : 1);  
  50.   
  51.         } catch (Exception e) {  
  52.             e.printStackTrace();  
  53.         }  
  54.     }  
  55.   
  56.     public static class MaxMapper extends Mapper<LongWritable, Text, LongWritable, NullWritable> {  
  57.         // 定义一个Long类型的最小值作为临时变量  
  58.         private Long max = Long.MIN_VALUE;  
  59.         // 定义输出去的value  
  60.         private LongWritable maxValue = new LongWritable();  
  61.   
  62.         @Override  
  63.         protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, LongWritable, NullWritable>.Context context) throws IOException,  
  64.                 InterruptedException {  
  65.             // 获取输入的行  
  66.             String line = value.toString();  
  67.             // 抛弃无效记录  
  68.             if (line == null || line.equals("")) {  
  69.                 return;  
  70.             }  
  71.             // 把line转换为数值  
  72.             long temp = Long.parseLong(line);  
  73.   
  74.             // 比较大小  
  75.             if (temp > max) {  
  76.                 // 把val赋值给tempMax  
  77.                 max = temp;  
  78.             }  
  79.   
  80.         }  
  81.   
  82.         /**  
  83.          * cleanUp()是指map函数执行完成之后就会调用,刚好满足我们的要求 因为map()函数执行完成之后我们单个任务的的最大值也就产生了  
  84.          */  
  85.         @Override  
  86.         protected void cleanup(Mapper<LongWritable, Text, LongWritable, NullWritable>.Context context) throws IOException, InterruptedException {  
  87.             // 把最后的处理结果写出去  
  88.             maxValue.set(max);  
  89.             context.write(maxValue, NullWritable.get());  
  90.         }  
  91.     }  
  92.   
  93.     /** 
  94.      * 汇总多个任务产生的最大值,再次比较 
  95.      */  
  96.     public static class MaxReducer extends Reducer<LongWritable, NullWritable, LongWritable, NullWritable> {  
  97.         // 定义一个参考的临时变量  
  98.         private Long max = Long.MIN_VALUE;  
  99.         // 定义输出的key  
  100.         private LongWritable maxValue = new LongWritable();  
  101.   
  102.         protected void reduce(LongWritable key, Iterable<NullWritable> value, Reducer<LongWritable, NullWritable, LongWritable, NullWritable>.Context context)  
  103.                 throws IOException, InterruptedException {  
  104.             if (key.get() > max) {  
  105.                 max = key.get();  
  106.             }  
  107.   
  108.         }  
  109.   
  110.         /** 
  111.          * reduce任务完成后写出去 
  112.          */  
  113.         protected void cleanup(Reducer<LongWritable, NullWritable, LongWritable, NullWritable>.Context context) throws IOException, InterruptedException {  
  114.             // 设置最大值  
  115.             maxValue.set(max);  
  116.             context.write(maxValue, NullWritable.get());  
  117.         }  
  118.     }  
  119. }  


程序运行结果:

 

MapReduce求最大值_第1张图片

你可能感兴趣的:(MapReduce求最大值)