MR大数据去重 & MR流程

居然被问到MR,好久没写MR了,此处凭借记忆和手记整理

一 、大数据去重

1. 以wc举例,来说明MR的过程

StringTokenizer(String str) :构造一个用来解析 str 的 StringTokenizer 对象。java 默认的分隔符是空格("")、制表符(\t)、换行符(\n)、回车符(\r)。

public class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
    IntWritable one = new IntWritable(1);
    Text word = new Text();

    public void map(Object key, Text value, Context context) throws IOException,InterruptedException {
        StringTokenizer itr = new StringTokenizer(value.toString());
        while(itr.hasMoreTokens()) {
            word.set(itr.nextToken());
            context.write(word, one);
        }
    }
}

public class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException,InterruptedException {
        int sum = 0;
        for(IntWritable val:values) {
            sum += val.get();
        }
        result.set(sum);
        context.write(key,result);
    }
}

2. 大数据去重

题目

/**
 * 题目:数据去重
 * 解题思路:将每行数据作为key值,value值为空
 *  2020-3-1 a
    2020-3-2 b
    2020-3-3 c
    2020-3-4 d
    2020-3-5 a
    2020-3-6 b
    2020-3-7 c
    2020-3-3 c
    2020-3-1 b
    2020-3-2 a
    2020-3-3 b
    2020-3-4 d
    2020-3-5 a
    2020-3-6 c
    2020-3-7 d
    2020-3-3 c
 */

2.1 当然此题可以用SQL:数据导入Hive,group by 

2.2 MR编程实现 map中 Value作为key写出;reduce中k-k写出

public class RemoveDupData {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);

        Job job = Job.getInstance(conf);
        job.setJar("wordcountJar/wordcount.jar");

        job.setMapperClass(RemoveDupDataMapper.class);
        job.setReducerClass(RemoveDupDataReducer.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);

        Path inputPath = new Path("input/RemoveDupData");
        Path outputPath = new Path("output/RemoveDupData");


        if(fs.isDirectory(outputPath)){
            fs.delete(outputPath,true);
        }
        FileInputFormat.setInputPaths(job,inputPath);
        FileOutputFormat.setOutputPath(job,outputPath);

        boolean waitForCompletion = job.waitForCompletion(true);
        System.exit(waitForCompletion ? 0 : 1 );
    }

    public static class RemoveDupDataMapper extends Mapper<LongWritable,Text,Text,NullWritable>{
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            context.write(value,NullWritable.get());
        }
    }

    public static class RemoveDupDataReducer extends Reducer<Text,NullWritable,Text,NullWritable>{
        @Override
        protected void reduce(Text key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
            context.write(key,NullWritable.get());
        }
    }
}

3. 两个文件求相同字符串

   3.1 如果文件不是特别大

读第一个文件,加入hashset,
读第二个文件,如果hashset中包含(contains),输出。

  3.2 如果文件比较大

1.ab两个文件mapreduce 去重追加输出为文件c
2.mapreduce 统计文件c次数出现为2的,输出

 

二 、MR的执行过程

网上看到一张图片,细品,贼有意思,分享给大家 ~

双击可点开查看大图

问题1 在Map任务和Reduce任务的过程中,一共发生了几次排序 ? 3次

1)环形缓冲区的每个分区按键排序。
当map函数产生输出时,会首先写入内存的环形缓冲区,当达到设定的阀值,在刷写磁盘之前,后台线程会将缓冲区的数据划分成相应的分区。
在环形缓冲区的每个分区中,后台线程按键进行内排序.

2)溢写文件归并排序。
在Map任务完成之前,磁盘上存在多个已经分好区,并排好序的,大小和缓冲区一样的溢写文件。
这时溢写文件将被合并成一个已分区且已排序的输出文件。
由于溢写文件已经经过第一次排序,所有合并文件只需要再做一次排序即可使输出文件整体有序。

3)reduce阶段归并多个map任务的输出文件。
在reduce阶段,需要将多个Map任务的输出文件copy到ReduceTask中后合并。
由于经过第二次排序,所以合并文件时只需再做一次排序即可使输出文件整体有序

在这3次排序中第一次是内存缓冲区做的内排序,使用的算法使快速排序,
第二次排序和第三次排序都是在文件合并阶段发生的,使用的是归并排序。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值