• Hadoop中自定义计数器


     

    一、环境

    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权威指南中写了统计百分比值,代码改改就能实现,就是一个总数除以错误数然
  • 相关阅读:
    小小的疑问和小小的想法
    为什么你的代码不能给别人看?
    linux之中对文件名和文件进行编码转换
    数据泵导入导出步骤
    杭电acm1266
    杭电acm2097
    杭电acm2019
    杭电acm1395(转自牛人代码)
    杭电acm1279
    杭电acm1412
  • 原文地址:https://www.cnblogs.com/java20130722/p/3206950.html
Copyright © 2020-2023  润新知