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

Hadoop 使用Combiner提高Map/Reduce程序效率的更多相关文章

  1. Hadoop实战:使用Combiner提高Map/Reduce程序效率

    好不easy算法搞定了.小数据測试也得到了非常好的结果,但是扔到进群上.挂上大数据就挂了.无休止的reduce不会结束了. .. .. .... .. ... .. ================= ...

  2. Hadoop学习笔记2 - 第一和第二个Map Reduce程序

    转载请标注原链接http://www.cnblogs.com/xczyd/p/8608906.html 在Hdfs学习笔记1 - 使用Java API访问远程hdfs集群中,我们已经可以完成了访问hd ...

  3. map reduce程序示例

    map reduce程序示例 package test2; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop. ...

  4. eclipse 中运行 Hadoop2.7.3 map reduce程序 出现错误(null) entry in command string: null chmod 0700

    运行map reduce任务报错: (null) entry in command string: null chmod 0700 解决办法: 在https://download.csdn.net/d ...

  5. 使用Python实现Map Reduce程序

    使用Python实现Map Reduce程序 起因 想处理一些较大的文件,单机运行效率太低,多线程也达不到要求,最终采用了集群的处理方式. 详细的讨论可以在v2ex上看一下. 步骤 MapReduce ...

  6. 第一个map reduce程序

    完成了第一个mapReduce例子,记录一下. 实验环境: hadoop在三台ubuntu机器上部署 开发在window7上进行 hadoop版本2.2.0 下载了hadoop-eclipse-plu ...

  7. Hadoop 2.4.1 Map/Reduce小结【原创】

    看了下MapReduce的例子.再看了下Mapper和Reducer源码,理清了参数的意义,就o了. public class Mapper<KEYIN, VALUEIN, KEYOUT, VA ...

  8. C#、JAVA操作Hadoop(HDFS、Map/Reduce)真实过程概述。组件、源码下载。无法解决:Response status code does not indicate success: 500。

    一.Hadoop环境配置概述 三台虚拟机,操作系统为:Ubuntu 16.04. Hadoop版本:2.7.2 NameNode:192.168.72.132 DataNode:192.168.72. ...

  9. Hadoop Map/Reduce的工作流

    问题描述 我们的数据分析平台是单一的Map/Reduce过程,由于半年来不断地增加需求,导致了问题已经不是那么地简单,特别是在Reduce阶段,一些大对象会常驻内存.因此越来越顶不住压力了,当前内存问 ...

随机推荐

  1. HDU - 6314:Matrix (广义容斥)(占位)

    Samwell Tarly is learning to draw a magical matrix to protect himself from the White Walkers. the ma ...

  2. 剑指Offer面试题:8.二进制中1的个数

    一 题目:二进制中1的个数 题目:请实现一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 二 可能引起死循环的解法 // 计算整数的二 ...

  3. bzoj 1725 Corn Fields

    Written with StackEdit. Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行\((1<=M<=12; 1<=N< ...

  4. 《DSP using MATLAB》示例Example7.22

    代码: h = [1, 2, 3, 4, 3, 2, 1]/15; M = length(h); n = 0:M-1; [Hr, w, a, L] = Hr_Type1(h); a L amax = ...

  5. Oracle 11G RAC:生产环境下架构

    转: it168网站  原创 作者:刘炳林 在真实环境搭建一套Oracle RAC就好比是一堂劳动课,劳动前需要准备好劳动工具,对劳动课内容有充分的认识;按照步骤一步一步进行,需要考虑劳动过程中可能遇 ...

  6. List<Map> 排序

    import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...

  7. mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理

    一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...

  8. PHP中的精确计算bcadd,bcsub,bcmul,bcdiv

    引言:一定要确保数据的准确性.这是一个好的程序员的基本素养. <?php /** * 精确加法 * @param [type] $a [description] * @param [type] ...

  9. bootstrap-datetimepicker如何只显示到日期

    bootstrap-datetimepicker 一般都是设置到时分秒,有时候并不需要,怎么处理呢? minView: "month", //选择日期后,不会再跳转去选择时分秒 1 ...

  10. Linux平台总线驱动设备模型

    platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...