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
- MR hadoop streaming job的學習 combinerHadoop
- 五、GO程式設計模式:MAP-REDUCEGo程式設計設計模式
- GO程式設計模式05:MAP-REDUCEGo程式設計設計模式
- forEach、map、reduce比較
- 【Hadoop】按照map-reduce的思想試述完整的pagerank計算過程Hadoop
- 例項講解hadoop中的map/reduce查詢(python語言實現HadoopPython
- python內建函式 map/reducePython函式
- JavaScript map和reduce的區別JavaScript
- 分散式計算與Map Reduce分散式
- 如何提高使用Java反射的效率?Java反射
- Map-Reduce資料分析之二
- map、reduce、filter、for...of、for...in等總結Filter
- 人人都能學會的python程式設計教程16:map和reducePython程式設計
- Python中的Map、Reduce和Filter函數語言程式設計PythonFilter函數程式設計
- Python學習筆記 - filter,map,reduce,zipPython筆記Filter
- python之高階函式map,reduce,filter用法Python函式Filter
- python-python的sao操作 map reduce filterPythonFilter
- 陣列的 map, filter ,sort和 reduce 用法陣列Filter
- javascript高階函式---filter---map---reduceJavaScript函式Filter
- JavaScript(1)高階函式filter、map、reduceJavaScript函式Filter
- 【譯】使用 Source Link 提高除錯效率除錯
- combiner函式函式
- 提高程式碼的執行效率(1)
- 程式設計技巧│提高 Javascript 程式碼效率的技巧程式設計JavaScript
- [譯] 圖解 Map、Reduce 和 Filter 陣列方法圖解Filter陣列
- 理解Swift高階函式之map, filter, reduceSwift函式Filter
- 可以提高程式設計師效率的工具!程式設計師
- python中快速處理關鍵字map,reduce,filterPythonFilter
- reduce實現filter,map 陣列扁平化等Filter陣列
- 陣列的forEach,map,filter,reduce,reduceRight,every,some方法陣列Filter
- JavaScript 4/30: 陣列的 map, filter 和 reduce 用法JavaScript陣列Filter
- 陣列的reduce操作+物件陣列的map操作陣列物件
- Python使用.NET開發的類庫來提高你的程式執行效率Python
- idea 使用外掛,提高工作效率Idea
- kotlin之plus、copyOf、reverse、forEach、filter、map、reduce、fold等函式解釋和使用KotlinFilter函式
- Java中的函數語言程式設計(七)流Stream的Map-Reduce操作Java函數程式設計
- Map-Reduce 思想在 ABAP 程式設計中的一個實際應用案例程式設計
- python常用函式進階(2)之map,filter,reduce,zipPython函式Filter