转自: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. 洛谷 UVA11388 GCD LCM

    UVA11388 GCD LCM Description of the title PDF The GCD of two positive integers is the largest intege ...

  2. bootstrap支持ie8 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法

    做一个在线系统,PC端也要做,但要兼容千恶的IE8[IE6 是万恶,打死我都不会管IE6],IE8 是我底线了md, 在IE8下 bottstrap 错乱,变形,不支持一些属性的问题,下面看了一篇 某 ...

  3. python-flask模块注入(SSTI)

    前言: 第一次遇到python模块注入是做ctf的时候,当时并没有搞懂原理所在,看了网上的资料,这里做一个笔记. flask基础: 先看一段python代码: from flask import fl ...

  4. docker镜像下载出现:received unexpected HTTP status: 500 Internal Server Error

    1.镜像下载总是出现报错:received unexpected HTTP status: 500 Internal Server Error 2.尝试多种方法: ①阿里云docke加速器:注册之后, ...

  5. Python函数装饰器

    装饰器的原则 1)不修改被修饰函数的源代码: 2)不修改被修饰函数的调用方式: 装饰器的知识点 = 高阶函数 + 函数嵌套 + 闭包 1. 只用高阶函数写装饰器--->有瑕疵 import ti ...

  6. Linux网络课程学习第三天

    第三天在线视频学习. 学习内容:继续详细介绍了第二章节 Linux常用命令的使用方法. 学习感受:万事开头难,作为Linux零基础的我相信在这本书学完之后会有所收获. 学习心得:记住刘老师的一句口头禅 ...

  7. 牛客网 —— 爱奇艺2020校招C++方向笔试题 总结

    错了5,6个,主要集中在数据库和操作系统上.    C++还需要提高熟练度. 总结 第6题: 折半查找树:根据二分查找构造得到的树,它一定是一个二叉排序树,是一个特殊的二叉排序树.  (接近于平衡二叉 ...

  8. GYCTF Node game

    考点: NodeJS 代码审计 SSRF 请求夹带 复现: 不太懂js,先留着吧,学懂了再记录

  9. html css二级导航栏

    二级导航栏制作: 1.将一级导航栏去除列表样式(list-style:none),并给予浮动,使其横向排列(float:left) 2.给每个li中添加一个<a></a>标签, ...

  10. Dubbo-服务注册中心之AbstractRegistry

    在dubbo中,关于注册中心Registry的有关实现封装在了dubbo-registry模块中.提供者(Provider)个消费者(Consumer)都是通过注册中心进行资源的调度.当服务启动时,p ...