转自: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. phpcms v9全站点击量排行代码

    前台: <ul> {pc:content action="sitehits" siteid="1" num="10" order ...

  2. python线程的条件变量Condition的用法实例

      Condition 对象就是条件变量,它总是与某种锁相关联,可以是外部传入的锁或是系统默认创建的锁.当几个条件变量共享一个锁时,你就应该自己传入一个锁.这个锁不需要你操心,Condition 类会 ...

  3. HTML5表单验证(4个实用的表单美化案例)

    multipart/form-data 在使用包含文件上传控件的表单时,必须使用autocomplete="on" 自动补全功能novalidate 不验证 <form en ...

  4. Python循环引用的解决方案

    1.延迟导入:即将 from xxx import yyy 放到函数或类的内部,从而使其作用域变成局部的,但是这样可能会对性能有些影响: 2.将 from xxx import yyy 转换成 imp ...

  5. centos7安装显示中文

    系统通过环境变量LANG设置语言格式编码 查看当前语言环境 echo $LANG 查看是否安装中文语言,Linux中通过locale来设置程序运行的不同语言环境 locale -a | grep 'z ...

  6. 在W10系统中配置Java环境变量后,cmd命令提示符找不到java

    java环境变量配置在W10系统上和以前有所区别,可能是W10版本导致也可能是W10一开始就出问题. 问题的表现就是你在环境变量里已经配置完JAVA_HOME,CLASSPATH,path之后在控制台 ...

  7. TCP常用拆包处理

    1.演示环境为windows 10 1903 2.演示代码 #include "pch.h" #include <iostream> #include <WinS ...

  8. Vue中axios有关请求头的几点小结

    在Vue前端中向后端发起http请求会有着两种写法:一种是在vue文件中直接导入axios模板,另外一种是使用Vue的属性$http. 1.在第一种方式中,在同一个工程中所添加的vue文件直接使用ax ...

  9. socket编程执行远程命令实现_python

    一.单客户端连接的例子: 服务端: import socket,os,subprocess server=socket.socket() server.bind(('localhost',1234)) ...

  10. VUE 路由参数改变重新刷新数据

    VUE 路由参数改变重新刷新数据 App.vue 里面使用路由,然后通过App.vue文件中的搜索功能搜索刷新路由文件中的列表. 修改 index.js 文件 首先在路由文件 index.js 文件中 ...