• Hadoop-MR实现日志清洗(二)


    (接上:Hadoop-MR实现日志清洗(一))

    4.groupbycount测试

    编写Hadoop-MR的groupbycount程序测试Hadoop运行环境,同时也是对mapreduce程序的一次复习。

    为了不影响logparser项目结构,单独创建了groupbycount项目,配置与logparser一致。

    初始结构:

    Image(3)

    4.1源文件准备

    源文件取自工作中部分数据集。

    下载地址:2018-08-29-15-03-13_1959.rar 

    样例数据:

    leeyk99    fr    fr    pc    Boutique    Day Dresses            18    0    0    20180828
    
    leeyk99    fr    fr    pc    Women    Accessories    Phone Cases        4    0    0    20180828
    
    leeyk99    fr    fr    pc    Women    Accessories    Scarves        5    0    0    20180828
    
    leeyk99    fr    fr    pc    Women    Beauty    Beauty Tools    Makeup Tools    1    0    0    20180828
    
    leeyk99    fr    fr    pc    Women    Clothing    Beachwear    Swimwear    4    0    0    20180828
    
    leeyk99    fr    fr    pc    Women    Clothing    Bottoms    Shorts    1    0    0    20180828

    数据结构:

    image

    4.2map函数

    package com.leeyk99.udp;
    
    import org.apache.hadoop.io.IntWritable;
    
    import org.apache.hadoop.io.LongWritable;
    
    import org.apache.hadoop.io.Text;
    
    import org.apache.hadoop.mapreduce.Mapper;
    
    import java.io.IOException;
    
    public class GroupByCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    
        private final int ONE=1;
    
        @Override
    
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
            //super.map(key, value, context);
    
            String line=value.toString();
    
            String[] lineSplit=line.split("	");
    
            String siteTp=lineSplit[0];
    
            context.write(new Text(siteTp),new IntWritable(ONE));
    
        }
    
    }

    4.3reduce函数

    package com.leeyk99.udp;
    
    import org.apache.hadoop.io.IntWritable;
    
    import org.apache.hadoop.io.Text;
    
    import org.apache.hadoop.mapreduce.Reducer;
    
    import java.io.IOException;
    
    //import java.util.Iterator;
    
    public class GroupByCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
    
        @Override
    
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    
            //super.reduce(key, values, context);
    
            Integer sum=0;
    
            /*Iterator<IntWritable> it=values.iterator();
    
            if(it.hasNext()){
    
                sum+=it.next().get();
    
            }*/
    
            for (IntWritable value : values ) {
    
                sum+=value.get();
    
            }
    
            context.write(key,new IntWritable(sum));
    
        }
    
    }

    4.4程序入口

    package com.leeyk99.udp;
    
    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;
    
    import java.io.File;
    
    //import java.io.IOException;
    
    public class GroupByCount {
    
        public static void main(String[] args) throws  Exception{//Exception范围比较大,包含IOException、InterruptedException
    
            if(args.length != 2){
    
                System.err.println("Usage: GroupByCount <input path> <output path>");
    
                System.exit(-1);
    
            }
    
            Job job=new Job();
    
            job.setJarByClass(GroupByCount.class);
    
            job.setJobName("job-GroupByCount");
    
            FileInputFormat.addInputPath(job, new Path(args[0]));
    
            FileOutputFormat.setOutputPath(job, new Path(args[1]));
    
            job.setMapperClass(GroupByCountMapper.class);
    
            job.setReducerClass(GroupByCountReducer.class);
    
            job.setOutputKeyClass(Text.class);
    
            job.setOutputValueClass(IntWritable.class);
    
            delDir(args[1]);
    
            System.exit(job.waitForCompletion(true)? 0 : 1);
    
        }
    
        private static void delDir(String path){
    
            File f=new File(path);
    
            if(f.exists()){
    
                if(f.isDirectory()){
    
                    String[] items=f.list();
    
                    for( String item : items ){
    
                        File f2=new File(path+"/"+item);
    
                        if(f2.isDirectory()){
    
                            delDir(path+"/"+item);
    
                        }
    
                        else{
    
                            f2.delete();
    
                        }
    
                    }
    
                }
    
                f.delete(); //删除文件或者最后的空目录
    
            }
    
            else{
    
                System.out.println("Output directory does not exist .");
    
            }
    
        }
    
    }

    4.5del函数

    写在入口函数中,也可以单独创建个类。

    private static void delDir(String path){
    
            File f=new File(path);
    
            if(f.exists()){
    
                if(f.isDirectory()){
    
                    String[] items=f.list();
    
                    for( String item : items ){
    
                        File f2=new File(path+"/"+item);
    
                        if(f2.isDirectory()){
    
                            delDir(path+"/"+item);
    
                        }
    
                        else{
    
                            f2.delete();
    
                        }
    
                    }
    
                }
    
                f.delete(); //删除文件或者最后的空目录
    
            }
    
            else{
    
                System.out.println("Output directory does not exist .");
    
            }
    
        }

    4.6测试

    在IDEA中需要设置下运行配置(Run/Debug Configurations):点击 + ,创建一个Application,选一下main class(一般输入项目名或类名,去查找的时候已经自动列出来可选的main了),设置下程序参数(Program arguments): input/ output/

    Image(4)

    得到:

    Image(5)

    点击 ▶ 运行,得到结果:

    Image(6)

    4.7小结

    本次测试使用mapreduce实现类似sql: select key,count(user_id) from tableName group by key 用法的功能。

    mapreduce程序的核心就是reduce函数中的计算实现,即对输入值的遍历处理,比如求和、计数、比较、取均、去重等多种运算。

    目前已完成  单维度求和、单维度计数。像Max、Min、取均这三类无需再尝试,因为这个三类和求和、计数类似。

    后续继续实现   单维度去重计数、单维度去重、无维度求和。

    至于多维度,其实很简单,因为在map函数中,得到多列后合并成一个字符串作为key(这几个字段的分隔符相当于在Hive中指定的列分隔符)。(初步思路)

    key和value的分隔符,如何指定呢(不是用默认的 )?后续做一次多维度单指标求和测试。

    那么多维度多指标求和如何做呢?后续继续测试。

  • 相关阅读:
    django中的分页管理
    python 时间字符串和时间戳之间的转换
    随机生成英文字母,并且统计频数
    html 中a标签的问题(无反应,跳转,调用方法)
    oracle sid,instance_name,db_name,oracle_sid之间的关系
    备份
    修改yum源
    sql基本语法
    第二章 shell编程基础
    第一章 初识shell程序
  • 原文地址:https://www.cnblogs.com/leeyuki/p/9561084.html
Copyright © 2020-2023  润新知