Mapreduce实例(三):数据去重

大家好,我是风云,欢迎大家关注我的博客 或者 微信公众号【笑看风云路】,在未来的日子里我们一起来学习大数据相关的技术,一起努力奋斗,遇见更好的自己!

实现思路

数据去重的最终目标是让原始数据中出现次数超过一次的数据在输出文件中只出现一次。在MapReduce流程中,map的输出<key,value>经过shuffle过程聚集成<key,value-list>后交给reduce。我们自然而然会想到将同一个数据的所有记录都交给一台reduce机器,无论这个数据出现多少次,只要在最终结果中输出一次就可以了。具体就是reduce的输入应该以数据作为key,而对value-list则没有要求(可以设置为空)。当reduce接收到一个<key,value-list>时就直接将输入的key复制到输出的key中,并将value设置成空值,然后输出<key,value>。

MaprReduce去重流程如下图所示:

img

编写代码

Mapper代码

  public static class Map extends Mapper<Object , Text , Text , NullWritable>  
    //map将输入中的value复制到输出数据的key上,并直接输出  
  {  
    private static Text newKey=new Text();      //从输入中得到的每行的数据的类型  
    public void map(Object key,Text value,Context context) throws IOException, InterruptedException  
      //实现map函数  
    {             //获取并输出每一次的处理过程  
      String line=value.toString();  
      System.out.println(line);  
      String arr[]=line.split("\t");  
      newKey.set(arr[1]);  
      context.write(newKey, NullWritable.get());  
      System.out.println(newKey);  
    }  
  } 

Mapper阶段采用Hadoop的默认的作业输入方式,把输入的value用split()方法截取,截取出的商品id字段设置为key,设置value为空,然后直接输出<key,value>。

Reducer代码

  public static class Reduce extends Reducer<Text, NullWritable, Text, NullWritable>{  
    public void reduce(Text key,Iterable<NullWritable> values,Context context) throws IOException, InterruptedException  
      //实现reduce函数  
    {  
      context.write(key,NullWritable.get());   //获取并输出每一次的处理过程  
    }  
  }  

map输出的<key,value>键值对经过shuffle过程,聚成<key,value-list>后,会交给reduce函数。reduce函数,不管每个key 有多少个value,它直接将输入的值赋值给输出的key,将输出的value设置为空,然后输出<key,value>就可以了。

完整代码

  package mapreduce;  
  import java.io.IOException;  
  import org.apache.hadoop.conf.Configuration;  
  import org.apache.hadoop.fs.Path;  
  import org.apache.hadoop.io.IntWritable;  
  import org.apache.hadoop.io.NullWritable;  
  import org.apache.hadoop.io.Text;  
  import org.apache.hadoop.mapreduce.Job;  
  import org.apache.hadoop.mapreduce.Mapper;  
  import org.apache.hadoop.mapreduce.Reducer;  
  import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;  
  import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;  
  public class Filter{  
    public static class Map extends Mapper<Object , Text , Text , NullWritable>{  
      private static Text newKey=new Text();  
      public void map(Object key,Text value,Context context) throws IOException, InterruptedException{  
        String line=value.toString();  
        System.out.println(line);  
        String arr[]=line.split("\t");  
        newKey.set(arr[1]);  
        context.write(newKey, NullWritable.get());  
        System.out.println(newKey);  
      }  
    }  
    public static class Reduce extends Reducer<Text, NullWritable, Text, NullWritable>{  
      public void reduce(Text key,Iterable<NullWritable> values,Context context) throws IOException, InterruptedException{  
        context.write(key,NullWritable.get());  
      }  
    }  
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException{  
      Configuration conf=new Configuration();  
      System.out.println("start");  
      Job job =new Job(conf,"filter");  
      job.setJarByClass(Filter.class);  
      job.setMapperClass(Map.class);  
      job.setReducerClass(Reduce.class);  
      job.setOutputKeyClass(Text.class);  
      job.setOutputValueClass(NullWritable.class);  
      job.setInputFormatClass(TextInputFormat.class);  
      job.setOutputFormatClass(TextOutputFormat.class);  
      Path in=new Path("hdfs://localhost:9000/mymapreduce2/in/buyer_favorite1");  
      Path out=new Path("hdfs://localhost:9000/mymapreduce2/out");  
      FileInputFormat.addInputPath(job,in);  
      FileOutputFormat.setOutputPath(job,out);  
      System.exit(job.waitForCompletion(true) ? 0 : 1);  
    }  
  }

-------------- end ----------------

微信公众号:扫描下方二维码或 搜索 笑看风云路 关注
笑看风云路

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑看风云路

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值