mapreduce编程实例(3)-求平均值

这个实例解决问题是:计算一天的每个小时中,网上新增多少条评论,并计算这些评论的平均长度。代码如下:

[java] view plain copy
  1. package mrdp.ch2;  
  2.   
  3. import java.io.DataInput;  
  4. import java.io.DataOutput;  
  5. import java.io.IOException;  
  6. import java.text.ParseException;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9. import java.util.Map;  
  10.   
  11. import mrdp.utils.MRDPUtils;  
  12.   
  13. import org.apache.hadoop.conf.Configuration;  
  14. import org.apache.hadoop.fs.Path;  
  15. import org.apache.hadoop.io.IntWritable;  
  16. import org.apache.hadoop.io.Text;  
  17. import org.apache.hadoop.io.Writable;  
  18. import org.apache.hadoop.mapreduce.Job;  
  19. import org.apache.hadoop.mapreduce.Mapper;  
  20. import org.apache.hadoop.mapreduce.Reducer;  
  21. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  22. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  23. import org.apache.hadoop.util.GenericOptionsParser;  
  24.   
  25. public class AverageDriver {  
  26.   
  27.     public static class SOAverageMapper extends  
  28.             Mapper<Object, Text, IntWritable, CountAverageTuple> {  
  29.   
  30.         private IntWritable outHour = new IntWritable();  
  31.         private CountAverageTuple outCountAverage = new CountAverageTuple();  
  32.   
  33.         private final static SimpleDateFormat frmt = new SimpleDateFormat(  
  34.                 "yyyy-MM-dd'T'HH:mm:ss.SSS");  
  35.   
  36.         @SuppressWarnings("deprecation")  
  37.         @Override  
  38.         public void map(Object key, Text value, Context context)  
  39.                 throws IOException, InterruptedException {  
  40.   
  41.             // Parse the input string into a nice map  
  42.             Map<String, String> parsed = MRDPUtils.transformXmlToMap(value  
  43.                     .toString());  
  44.   
  45.             // Grab the "CreationDate" field,  
  46.             // since it is what we are grouping by  
  47.             String strDate = parsed.get("CreationDate");  
  48.   
  49.             // Grab the comment to find the length  
  50.             String text = parsed.get("Text");  
  51.   
  52.             // .get will return null if the key is not there  
  53.             if (strDate == null || text == null) {  
  54.                 // skip this record  
  55.                 return;  
  56.             }  
  57.   
  58.             try {  
  59.                 // get the hour this comment was posted in  
  60.                 Date creationDate = frmt.parse(strDate);  
  61.                 outHour.set(creationDate.getHours());  
  62.   
  63.                 // get the comment length  
  64.                 outCountAverage.setCount(1);  
  65.                 outCountAverage.setAverage(text.length());  
  66.   
  67.                 // write out the user ID with min max dates and count  
  68.                 context.write(outHour, outCountAverage);  
  69.   
  70.             } catch (ParseException e) {  
  71.                 System.err.println(e.getMessage());  
  72.                 return;  
  73.             }  
  74.         }  
  75.     }  
  76.   
  77.     public static class SOAverageReducer  
  78.             extends  
  79.             Reducer<IntWritable, CountAverageTuple, IntWritable, CountAverageTuple> {  
  80.         private CountAverageTuple result = new CountAverageTuple();  
  81.   
  82.         @Override  
  83.         public void reduce(IntWritable key, Iterable<CountAverageTuple> values,  
  84.                 Context context) throws IOException, InterruptedException {  
  85.   
  86.             float sum = 0;  
  87.             float count = 0;  
  88.   
  89.             // Iterate through all input values for this key  
  90.             for (CountAverageTuple val : values) {  
  91.                 sum += val.getCount() * val.getAverage();  
  92.                 count += val.getCount();  
  93.             }  
  94.   
  95.             result.setCount(count);  
  96.             result.setAverage(sum / count);  
  97.   
  98.             context.write(key, result);  
  99.         }  
  100.     }  
  101.   
  102.     public static void main(String[] args) throws Exception {  
  103.         Configuration conf = new Configuration();  
  104.         String[] otherArgs = new GenericOptionsParser(conf, args)  
  105.                 .getRemainingArgs();  
  106.         if (otherArgs.length != 2) {  
  107.             System.err.println("Usage: AverageDriver <in> <out>");  
  108.             System.exit(2);  
  109.         }  
  110.         @SuppressWarnings("deprecation")  
  111.         Job job = new Job(conf, "StackOverflow Average Comment Length");  
  112.         job.setJarByClass(AverageDriver.class);  
  113.         job.setMapperClass(SOAverageMapper.class);  
  114.         job.setCombinerClass(SOAverageReducer.class);  
  115.         job.setReducerClass(SOAverageReducer.class);  
  116.         job.setOutputKeyClass(IntWritable.class);  
  117.         job.setOutputValueClass(CountAverageTuple.class);  
  118.         FileInputFormat.addInputPath(job, new Path(otherArgs[0]));  
  119.         FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));  
  120.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  121.     }  
  122.   
  123.     public static class CountAverageTuple implements Writable {  
  124.         private float count = 0f;  
  125.         private float average = 0f;  
  126.   
  127.         public float getCount() {  
  128.             return count;  
  129.         }  
  130.   
  131.         public void setCount(float count) {  
  132.             this.count = count;  
  133.         }  
  134.   
  135.         public float getAverage() {  
  136.             return average;  
  137.         }  
  138.   
  139.         public void setAverage(float average) {  
  140.             this.average = average;  
  141.         }  
  142.   
  143.         @Override  
  144.         public void readFields(DataInput in) throws IOException {  
  145.             count = in.readFloat();  
  146.             average = in.readFloat();  
  147.         }  
  148.   
  149.         @Override  
  150.         public void write(DataOutput out) throws IOException {  
  151.             out.writeFloat(count);  
  152.             out.writeFloat(average);  
  153.         }  
  154.   
  155.         @Override  
  156.         public String toString() {  
  157.             return count + "\t" + average;  
  158.         }  
  159.     }  
  160. }  
这个程序也比较简单,重写writable,然后计算。其流程图如下:

mapreduce编程实例(3)-求平均值_第1张图片

更多 0

你可能感兴趣的:(mapreduce编程实例(3)-求平均值)