Hadoop 使用Combiner提高Map/Reduce程式效率
眾所周知,Hadoop框架使用Mapper將資料處理成一個
在上述過程中,我們看到至少兩個效能瓶頸:
- 如果我們有10億個資料,Mapper會生成10億個鍵值對在網路間進行傳輸,但如果我們只是對資料求最大值,那麼很明顯的Mapper只需要輸出它所知道的最大值即可。這樣做不僅可以減輕網路壓力,同樣也可以大幅度提高程式效率。
- 使用專利中的國家一項來闡述資料傾斜這個定義。這樣的資料遠遠不是一致性的或者說平衡分佈的,由於大多數專利的國家都屬於美國,這樣不僅Mapper中的鍵值對、中間階段(shuffle)的鍵值對等,大多數的鍵值對最終會聚集於一個單一的Reducer之上,壓倒這個Reducer,從而大大降低程式的效能。
Hadoop透過使用一個介於Mapper和Reducer之間的Combiner步驟來解決上述瓶頸。你可以將Combiner視為Reducer的一個幫手,它主要是為了削減Mapper的輸出從而減少網
絡頻寬和Reducer之上的負載。如果我們定義一個Combiner,MapReducer框架會對中間資料多次地使用它進行處理。
如果Reducer只執行簡單的分散式方法,例如最大值、最小值、或者計數,那麼我們可以讓Reducer自己作為Combiner。但許多有用的方法不是分散式的。以下我們使用求平均值作為例子進行講解:
Mapper輸出它所處理的鍵值對,為了使單個DataNode計算平均值Reducer會對它收到的
由於Reducer將它所收到的
程式碼如下:
- package com;
- import java.io.IOException;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.conf.Configured;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.DoubleWritable;
- import org.apache.hadoop.io.LongWritable;
- 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;
- import org.apache.hadoop.util.Tool;
- import org.apache.hadoop.util.ToolRunner;
- public class AveragingWithCombiner extends Configured implements Tool {
-
public static class MapClass extends Mapper
{ - static enum ClaimsCounters { MISSING, QUOTED };
- // Map Method
- public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
- String fields[] = value.toString().split(",", -20);
- String country = fields[4];
- String numClaims = fields[8];
- if (numClaims.length() > 0 && !numClaims.startsWith("\"")) {
- context.write(new Text(country), new Text(numClaims + ",1"));
- }
- }
- }
-
public static class Reduce extends Reducer
{ - // Reduce Method
-
public void reduce(Text key, Iterable
values, Context context) throws IOException, InterruptedException { - double sum = 0;
- int count = 0;
- for (Text value : values) {
- String fields[] = value.toString().split(",");
- sum += Double.parseDouble(fields[0]);
- count += Integer.parseInt(fields[1]);
- }
- context.write(key, new DoubleWritable(sum/count));
- }
- }
-
public static class Combine extends Reducer
{ - // Reduce Method
-
public void reduce(Text key, Iterable
values, Context context) throws IOException, InterruptedException { - double sum = 0;
- int count = 0;
- for (Text value : values) {
- String fields[] = value.toString().split(",");
- sum += Double.parseDouble(fields[0]);
- count += Integer.parseInt(fields[1]);
- }
- context.write(key, new Text(sum+","+count));
- }
- }
- // run Method
- public int run(String[] args) throws Exception {
- // Create and Run the Job
- Job job = new Job();
- job.setJarByClass(AveragingWithCombiner.class);
- FileInputFormat.addInputPath(job, new Path(args[0]));
- FileOutputFormat.setOutputPath(job, new Path(args[1]));
- job.setJobName("AveragingWithCombiner");
- job.setMapperClass(MapClass.class);
- job.setCombinerClass(Combine.class);
- job.setReducerClass(Reduce.class);
- job.setInputFormatClass(TextInputFormat.class);
- job.setOutputFormatClass(TextOutputFormat.class);
- job.setOutputKeyClass(Text.class);
- job.setOutputValueClass(Text.class);
- System.exit(job.waitForCompletion(true) ? 0 : 1);
- return 0;
- }
- public static void main(String[] args) throws Exception {
- int res = ToolRunner.run(new Configuration(), new AveragingWithCombiner(), args);
- System.exit(res);
- }
- }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29754888/viewspace-1220351/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Hadoop Map Reduce 漫談Hadoop
- Hadoop 2.6 以WordCount為例理解Map ReduceHadoop
- Hadoop--Map/Reduce實現多表連結Hadoop
- Hadoop-Map/Reduce實現實現倒排索引Hadoop索引
- Hadoop--map/reduce實現單詞計數Hadoop
- Hadoop 2.6 使用Map Reduce實現矩陣相乘1 矩陣轉置Hadoop矩陣
- Hadoop-Map/Reduce之單表連線的實現Hadoop
- 五、GO程式設計模式:MAP-REDUCEGo程式設計設計模式
- GO程式設計模式05:MAP-REDUCEGo程式設計設計模式
- python 學習--map 和 reduce的使用Python
- map/reduce實現 排序排序
- hadoop中Combiner使用中需要注意的地方Hadoop
- hadoop 多表join:Map side join及Reduce side join範例HadoopIDE
- 在JavaScript函數語言程式設計裡使用Map和Reduce方法JavaScript函數程式設計
- Python函數語言程式設計-map/reducePython函數程式設計
- 【Hadoop】按照map-reduce的思想試述完整的pagerank計算過程Hadoop
- 提高C程式效率的方法C程式
- 分散式計算與Map Reduce分散式
- Python map, reduce, filter和sortedPythonFilter
- Mongodb 的中資料統計神器Map_Reduce的使用MongoDB
- 例項講解hadoop中的map/reduce查詢(python語言實現HadoopPython
- 如何提高 Python 程式碼效率Python
- 如何提高使用Java反射的效率?Java反射
- [Java]使用lombok提高編碼效率JavaLombok
- 使用 RelProxy 提高 Java 開發效率Java
- python內建函式 map/reducePython函式
- Map-Reduce資料分析之二
- map、reduce、filter、for...of、for...in等總結Filter
- Java,Pyhon,Scala比較(一)map,reduceJava
- map/reduce實現資料去重
- MR hadoop streaming job的學習 combinerHadoop
- hadoop之 reduce個數控制Hadoop
- Hadoop原始碼篇--Reduce篇Hadoop原始碼
- 使用Bulk Collect提高Oracle查詢效率Oracle
- JavaScript(1)高階函式filter、map、reduceJavaScript函式Filter
- 陣列的 map, filter ,sort和 reduce 用法陣列Filter
- javascript高階函式---filter---map---reduceJavaScript函式Filter
- lambda map filter reduce zip 以及列表推導Filter