代码改变世界

Hadoop中自定义计数器

2013-04-22 11:01  java20130722  阅读(237)  评论(0编辑  收藏  举报

 

一、环境

1、hadoop 0.20.2

2、操作系统Linux

二、背景

1、最近写MR的代码,总在想统计一些错误的数据出现的次数,发现如果都写在reduce的输出里太难看了,所以想找办法专门输出一些统计数字。

2、翻看《hadoop权威指南》第8章第1节的时候发现能够自定义计数器,但都是基于0.19版本写的,好多函数都不对,改动相对较大。

3、基于上面2个理由,写个文档,记录一下。

三、实现

1、前提:写入一个文件,规范的是3个字段,“/t”划分,有2条异常,一条是2个字段,一条是4个字段,内容如下:

jim    1       28 kate     0       26 tom    1 kaka     1       22 lily     0       29      22
2、统计处不规范的数据。我没有写reduce,因为不需要输出,代码如下,先看代码
  1. import java.io.IOException;  
  2.   
  3. import org.apache.hadoop.conf.Configuration;  
  4. import org.apache.hadoop.fs.Path;  
  5. import org.apache.hadoop.io.LongWritable;  
  6. import org.apache.hadoop.io.Text;  
  7. import org.apache.hadoop.mapreduce.Counter;  
  8. import org.apache.hadoop.mapreduce.Job;  
  9. import org.apache.hadoop.mapreduce.Mapper;  
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  12. import org.apache.hadoop.util.GenericOptionsParser;  
  13.   
  14. public class MyCounter {  
  15.   
  16.     public static class MyCounterMap extends Mapper<LongWritable, Text, Text, Text> {  
  17.           
  18.         public static Counter ct = null;  
  19.   
  20.         protected void map(LongWritable key, Text value,  
  21.                 org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, Text>.Context context)  
  22.                 throws java.io.IOException, InterruptedException {  
  23.             String arr_value[] = value.toString().split("/t");  
  24.             if (arr_value.length > 3) {  
  25.                 ct = context.getCounter("ErrorCounter""toolong");  
  26.                 ct.increment(1);  
  27.             } else if (arr_value.length < 3) {  
  28.                 ct = context.getCounter("ErrorCounter""tooshort");  
  29.                 ct.increment(1);  
  30.             }  
  31.         }  
  32.     }  
  33.   
  34.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  35.         Configuration conf = new Configuration();  
  36.         String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
  37.         if (otherArgs.length != 2) {  
  38.             System.err.println("Usage: MyCounter <in> <out>");  
  39.             System.exit(2);  
  40.         }  
  41.   
  42.         Job job = new Job(conf, "MyCounter");  
  43.         job.setJarByClass(MyCounter.class);  
  44.   
  45.         job.setMapperClass(MyCounterMap.class);  
  46.   
  47.         FileInputFormat.addInputPath(job, new Path(otherArgs[0]));  
  48.         FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));  
  49.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  50.     }  
  51. }  

3、启动命令如下:
hadoop jar /jz/jar/Hadoop_Test.jar jz.MyCounter /jz/* /jz/06
对于小于3个字段的采用tooshort统计,大于3个字段的采用toolong统计
 
4、结果如下(红色部分):
  1. 10/08/04 17:29:15 INFO mapred.JobClient: Job complete: job_201008032120_0019  
  2. 10/08/04 17:29:15 INFO mapred.JobClient: Counters: 18  
  3. 10/08/04 17:29:15 INFO mapred.JobClient:   Job Counters   
  4. 10/08/04 17:29:15 INFO mapred.JobClient:     Launched reduce tasks=1  
  5. 10/08/04 17:29:15 INFO mapred.JobClient:     Rack-local map tasks=1  
  6. 10/08/04 17:29:15 INFO mapred.JobClient:     Launched map tasks=6  
  7. 10/08/04 17:29:15 INFO mapred.JobClient:   ErrorCounter  
  8. 10/08/04 17:29:15 INFO mapred.JobClient:     tooshort=1  
  9. 10/08/04 17:29:15 INFO mapred.JobClient:     toolong=1  
  10. 10/08/04 17:29:15 INFO mapred.JobClient:   FileSystemCounters  
  11. 10/08/04 17:29:15 INFO mapred.JobClient:     FILE_BYTES_READ=6  
  12. 10/08/04 17:29:15 INFO mapred.JobClient:     HDFS_BYTES_READ=47  
  13. 10/08/04 17:29:15 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=234  
  14. 10/08/04 17:29:15 INFO mapred.JobClient:   Map-Reduce Framework  
  15. 10/08/04 17:29:15 INFO mapred.JobClient:     Reduce input groups=0  
  16. 10/08/04 17:29:15 INFO mapred.JobClient:     Combine output records=0  
  17. 10/08/04 17:29:15 INFO mapred.JobClient:     Map input records=5  
  18. 10/08/04 17:29:15 INFO mapred.JobClient:     Reduce shuffle bytes=36  
  19. 10/08/04 17:29:15 INFO mapred.JobClient:     Reduce output records=0  
  20. 10/08/04 17:29:15 INFO mapred.JobClient:     Spilled Records=0  
  21. 10/08/04 17:29:15 INFO mapred.JobClient:     Map output bytes=0  
  22. 10/08/04 17:29:15 INFO mapred.JobClient:     Combine input records=0  
  23. 10/08/04 17:29:15 INFO mapred.JobClient:     Map output records=0  
  24. 10/08/04 17:29:15 INFO mapred.JobClient:     Reduce input records=0  
四、总结
1、其实hadoop权威指南写的很清楚了,但是由于版本不一样,所以很多方法也不同,总一下,主要有以下不同:
不再需要枚举的类型、计数器名不在需要写properties文件,调用的方法在context中都封装了。
2、hadoop权威指南中写了统计百分比值,代码改改就能实现,就是一个总数除以错误数然