转自:http://blog.csdn.net/jokes000/article/details/7072963

众所周知,Hadoop框架使用Mapper将数据处理成一个<key,value>键值对,再网络节点间对其进行整理(shuffle),然后使用Reducer处理数据并进行最终输出。

在上述过程中,我们看到至少两个性能瓶颈:

  1. 如果我们有10亿个数据,Mapper会生成10亿个键值对在网络间进行传输,但如果我们只是对数据求最大值,那么很明显的Mapper只需要输出它所知道的最大值即可。这样做不仅可以减轻网络压力,同样也可以大幅度提高程序效率。
  2. 使用专利中的国家一项来阐述数据倾斜这 个定义。这样的数据远远不是一致性的或者说平衡分布的,由于大多数专利的国家都属于美国,这样不仅Mapper中的键值对、中间阶段(shuffle)的 键值对等,大多数的键值对最终会聚集于一个单一的Reducer之上,压倒这个Reducer,从而大大降低程序的性能。

Hadoop通过使用一个介于Mapper和Reducer之间的Combiner步骤来解决上述瓶颈。你可以将Combiner视为Reducer的一个帮手,它主要是为了削减Mapper的输出从而减少网

络带宽和Reducer之上的负载。如果我们定义一个Combiner,MapReducer框架会对中间数据多次地使用它进行处理。

如果Reducer只运行简单的分布式方法,例如最大值、最小值、或者计数,那么我们可以让Reducer自己作为Combiner。但许多有用的方法不是分布式的。以下我们使用求平均值作为例子进行讲解:

Mapper输出它所处理的键值对,为了使单个DataNode计算平均值Reducer会对它收到的<key,value>键值对进行排序,求和。

由于Reducer将它所收到的<key,value>键值的数目视为输入数据中的<key,value>键值对的数目,此时使用Combiner的主要障碍就是计数操作。我们可以重写MapReduce程序来明确的跟踪计数过程。

代码如下:

  1. package com;
  2. import java.io.IOException;
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.conf.Configured;
  5. import org.apache.hadoop.fs.Path;
  6. import org.apache.hadoop.io.DoubleWritable;
  7. import org.apache.hadoop.io.LongWritable;
  8. import org.apache.hadoop.io.Text;
  9. import org.apache.hadoop.mapreduce.Job;
  10. import org.apache.hadoop.mapreduce.Mapper;
  11. import org.apache.hadoop.mapreduce.Reducer;
  12. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  13. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
  14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  15. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  16. import org.apache.hadoop.util.Tool;
  17. import org.apache.hadoop.util.ToolRunner;
  18. public class AveragingWithCombiner extends Configured implements Tool {
  19. public static class MapClass extends Mapper<LongWritable,Text,Text,Text> {
  20. static enum ClaimsCounters { MISSING, QUOTED };
  21. // Map Method
  22. public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  23. String fields[] = value.toString().split(",", -20);
  24. String country = fields[4];
  25. String numClaims = fields[8];
  26. if (numClaims.length() > 0 && !numClaims.startsWith("\"")) {
  27. context.write(new Text(country), new Text(numClaims + ",1"));
  28. }
  29. }
  30. }
  31. public static class Reduce extends Reducer<Text,Text,Text,DoubleWritable> {
  32. // Reduce Method
  33. public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
  34. double sum = 0;
  35. int count = 0;
  36. for (Text value : values) {
  37. String fields[] = value.toString().split(",");
  38. sum += Double.parseDouble(fields[0]);
  39. count += Integer.parseInt(fields[1]);
  40. }
  41. context.write(key, new DoubleWritable(sum/count));
  42. }
  43. }
  44. public static class Combine extends Reducer<Text,Text,Text,Text> {
  45. // Reduce Method
  46. public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
  47. double sum = 0;
  48. int count = 0;
  49. for (Text value : values) {
  50. String fields[] = value.toString().split(",");
  51. sum += Double.parseDouble(fields[0]);
  52. count += Integer.parseInt(fields[1]);
  53. }
  54. context.write(key, new Text(sum+","+count));
  55. }
  56. }
  57. // run Method
  58. public int run(String[] args) throws Exception {
  59. // Create and Run the Job
  60. Job job = new Job();
  61. job.setJarByClass(AveragingWithCombiner.class);
  62. FileInputFormat.addInputPath(job, new Path(args[0]));
  63. FileOutputFormat.setOutputPath(job, new Path(args[1]));
  64. job.setJobName("AveragingWithCombiner");
  65. job.setMapperClass(MapClass.class);
  66. job.setCombinerClass(Combine.class);
  67. job.setReducerClass(Reduce.class);
  68. job.setInputFormatClass(TextInputFormat.class);
  69. job.setOutputFormatClass(TextOutputFormat.class);
  70. job.setOutputKeyClass(Text.class);
  71. job.setOutputValueClass(Text.class);
  72. System.exit(job.waitForCompletion(true) ? 0 : 1);
  73. return 0;
  74. }
  75. public static void main(String[] args) throws Exception {
  76. int res = ToolRunner.run(new Configuration(), new AveragingWithCombiner(), args);
  77. System.exit(res);
  78. }
  79. }

(转)Hadoop Combiner的更多相关文章

  1. Hadoop学习笔记—8.Combiner与自定义Combiner

    一.Combiner的出现背景 1.1 回顾Map阶段五大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步凑,其中在Map阶段总共五个步骤,如下图所示: ...

  2. Hadoop中Combiner的使用

    注:转载自http://blog.csdn.net/ipolaris/article/details/8723782 在MapReduce中,当map生成的数据过大时,带宽就成了瓶颈,怎样精简压缩传给 ...

  3. Hadoop(十六)之使用Combiner优化MapReduce

    前言 前面的一篇给大家写了一些MapReduce的一些程序,像去重.词频统计.统计分数.共现次数等.这一篇给大家介绍的是关于Combiner优化操作. 一.Combiner概述 1.1.为什么需要Co ...

  4. Hadoop基础-MapReduce的Combiner用法案例

    Hadoop基础-MapReduce的Combiner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编写年度最高气温统计 如上图说所示:有一个temp的文件,里面存放 ...

  5. hadoop学习;Streaming,aggregate;combiner

    hadoop streaming同意我们使用不论什么可运行脚本来处理按行组织的数据流,数据取自UNIX的标准输入STDIN,并输出到STDOUT 我们能够用 linux命令管道查看文本有多少行,cat ...

  6. 【Hadoop】Combiner的本质是迷你的reducer,不能随意使用

    问题提出: 众所周知,Hadoop框架使用Mapper将数据处理成一个<key,value>键值对,再网络节点间对其进行整理(shuffle),然后使用Reducer处理数据并进行最终输出 ...

  7. Hadoop的Combiner

    在很多MapReduce应用的场景中,假设能在向reducer分发mapper结果之前做一下"本地化Reduce".一wordcount为样例,假设作业处理中的文件单词中" ...

  8. hadoop map任务Combiner被调用的源码逻辑简要分析

      从MapTask类中分析下去,看一下map任务是如何被调用并执行的.   入口方法是MapTask的run方法,看一下run方法的相关介绍:   org.apache.hadoop.mapred. ...

  9. Hadoop 使用Combiner提高Map/Reduce程序效率

    众所周知,Hadoop框架使用Mapper将数据处理成一个<key,value>键值对,再网络节点间对其进行整理(shuffle),然后使用Reducer处理数据并进行最终输出. 在上述过 ...

随机推荐

  1. 在IE8的基础上安装IE11

    安装包下载 链接:https://pan.baidu.com/s/1WAuyMg_SrfVa0wLjoop5Jw   提取码:nh1r 安装方式 先运行 - EIE11_ZH-CN_WOL_WIN76 ...

  2. JavaSE学习笔记(4)---抽象类和接口

    JavaSE学习笔记(4)---抽象类和接口 抽象方法和抽象类 ·抽象方法 使用abstract修饰的方法,没有方法体,只有声明.定义的是一种"规范",就是告诉子类必须要给抽象方法 ...

  3. 移动Web开发-WebApp(flex布局+移动端导航案例)

    实际开发中的像素:css像素设备像素比dpr=设备像素/css像素标清屏dpr=1 高清屏dpr=2缩放改变的是css像素大小PPI(每英寸的物理像素点)=根号(屏幕横向分辨率²+屏幕纵向分辨率²)/ ...

  4. 基于TCP协议Socket通信

    服务器线程处理类 package demo4; import java.io.*; import java.net.Socket; /** * 服务器线程处理类 * @ClassName Server ...

  5. wfuzz的使用

    用于模糊测试,测试过滤字符 转载:https://www.secpulse.com/archives/81560.html https://www.freebuf.com/sectool/173746 ...

  6. P1041 传染病控制【暴搜】

    P1041 传染病控制 提交 10.78k 通过 3.74k 时间限制 1.00s 内存限制 125.00MB 题目提供者CCF_NOI 难度提高+/省选- 历史分数100 提交记录 查看题解 标签 ...

  7. Centos7 同时运行PHP5.2和PHP7.1配置

    工作环境一直都是lnmp,其中PHP已经升级到7.1版本了.突然有份代码需要运行在PHP5.2上.但是之前的环境还是需要的,所以需要在centos中再安装PHP5.2. 0.之前的php7安装在/us ...

  8. JVM的小理解

    1.开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器 ...

  9. 0级搭建类008-Ubuntu Server Linux安装 (18.04.2) 公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...

  10. 实现Windows数据更新

    一.枚举 枚举是一组描述性的名称 定义一组有限的值,不能包含方法 对可能的值进行约束 .定义枚举类 public enum Gender { Male,Female } .使用枚举表示整数值 publ ...