MapReduce執行框架的組件和執行流程

   MapReduce是Hadoop核心框架之一,是一種並行計算的編程模型。當我們利用Hadoop進行大數據處理時,很大一部分工作就是基於MapReduce編寫數據處理程序,所以對於掌握MapReduce執行框架的組件和執行流程非常重要。本文藉助WordCount程序來講述MapReduce執行框架的組件和執行流程。

   WordCount程序的作用是統計文本中出現的每個單詞的次數。下面先給出WorkCount程序代碼。

package MapReduceDemo;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
//statistics the number of words
public class WordCountMain {
	public static void main(String[] args)throws Exception {
		//create job = map + reduce
		Configuration conf = new Configuration();
		//create Job
		Job job = Job.getInstance(conf);
		//the entry of job
		job.setJarByClass(WordCountMain.class);
		//the mapper of job
		job.setMapperClass(WordCountMapper.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(LongWritable.class);
		//the reducer of job
		job.setReducerClass(WordCountReducer.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(LongWritable.class);
		//input and output
		TextInputFormat.setInputPaths(job, new Path(args[0]));
		TextOutputFormat.setOutputPath(job, new Path(args[1]));		
		//submit job
		job.waitForCompletion(true);
	}
}

package MapReduceDemo;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WordCountMapper extends Mapper<LongWritable, Text, Text, LongWritable> {

	@Override
	protected void map(LongWritable key, Text value,Context context)throws IOException, InterruptedException {
		//split string 
		String data = value.toString();
		String[] words = data.split(" ");
		for(String word : words){
			context.write(new Text(word),new LongWritable(1));
		}
	}
}

package MapReduceDemo;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordCountReducer extends Reducer<Text, LongWritable, Text, LongWritable>{

	@Override
	protected void reduce(Text arg0, Iterable<LongWritable> arg1,Context arg2)throws IOException,InterruptedException {
		long sum = 0;
		for(LongWritable a : arg1){
			sum += a.get();
		}
		arg2.write(arg0, new LongWritable(sum));
	}
}

   下面我們就以WordCount程序的執行流程來闡述MapReduce執行的幾個階段和所需的組件。

   第一階段:以指定格式從HDFS上讀取數據。

   要進行數據處理的第一步當然是讀取數據,並且爲了方便進行數據處理,數據必須以特定的某種格式進行讀取。在MapReduce中InputFormat類就是讀取數據的組件。我們知道MapReduce的核心思想是“分而治之”,所以一份大數據就必須要分成多份小數據來處理,而InputFormat類也擔當將大數據分塊的任務。下面是InputFormat類的職責。

   (1)以某種格式讀取數據。

   (2)將讀取的一份大數據分成邏輯意義上完整的多個塊,其中每一個塊是一個Mapper的輸入。

   (3)提供一個RecordReader類,用於將Mapper的輸入(即第二中的塊)轉化爲若干條輸入記錄。

   Hadoop提供了一些常用的InputFormat類,每一個InputFormat類都採用特定的格式讀取數據並分塊。下面給出三個常用的InputFormat類。

InputFormat類描述
TextInputFormat對文本文件一行一行的讀取當前行的偏移量當前行內容
KeyValueInputFormat將行解析爲鍵值對行內首個製表符前的內容行內其餘內容
SequenceFileInputFormat專用於Hadoop的高性能的二進制格式用戶定義用戶定義

   在WordCount中,我使用的是TextInputFomat類。HDFS上的源數據如下。

I Love Beijing
I Love China
Beijng is the capital of China

   經過TextInputFomat類的讀取和分塊(我們假設有兩個分塊),以下是輸入到每個Mapper中的鍵值對。

第一個Mapper的輸入:   0:I love Beijing
第二個Mapper的輸入:   0:I love China   14:Beijing is the capital of China

   第二階段:在Mapper中處理每一個鍵值對

   怎麼處理鍵值對完全是由用戶定義的,由於WordCount程序的任務是求每個單詞的個數,所以我們就對值進行分詞處理了。下面是每一個Mapper的輸出。

第一個Mapper的輸出:  I:1,Love:1,Beijing:1
第二個Mapper的輸出:  I:1,Love:1,China:1,Beijing:1,is:1,the:1,capital:1,of:1,China:1

   第三階段:對Mapper的輸出進行合併、分區和排序處理之後作爲Reducer的輸入。

   每一個Mapper的輸出要傳輸到Reducer中進行處理,在第二個Mapper的輸出中,我們發現有兩個 China:1要進行傳輸,我們能不能把本來要單獨進行兩次傳輸的鍵值對改進成一次傳輸,這樣做的目的就是減少網絡帶寬。在Hadoop中有一個Combiner類就是做這種改進的,它把具有相同主鍵的鍵值對合並在一起成爲一個新的鍵值對,新鍵值對的主鍵還是原來的主鍵,值變爲一個列表,列表中的元素爲原來每一個鍵值對的值。如上述的兩個 China :1 可以合併成 China:[1,1]。

   一個鍵值對放在哪個Reducer節點上進行處理是有關係的,爲了避免不同Reducer節點的數據相關性,我們要將具有相同主鍵的鍵值對放在同一個Reducer節點上進行處理。比如第一個Mapper輸出的 I:1 和第二個Mapper輸出的 I:1就要放在同一個Reducer節點上處理。Hadoop提供的Partitioner類就是起這個作用的。下圖是每一個鍵值對的分區結果。


   鍵值對進入Reducer節點之後,在每一個Reducer節點內部,會對所有鍵值對進行一個排序。排序默認是以主鍵進行升序的,當然用戶可以自己定義排序操作,這需要重載Hadoop中的Sort類接口函數。在WordCount程序中我們使用默認排序。

   第四階段:在Reducer中處理並以指定格式輸出最後結果。

   Reducer主要是做一些整理和進一步的處理,其中的邏輯主要由用戶決定,用戶需要重載其reduce()方法。最後結果的輸出和源數據的輸入一樣都有格式要求,Hadoop中的OutputFormat類就提供以指定格式進行輸出的功能。下面介紹幾個常用的OutputFormat類。

OutputFormat描述
TextOutputFormat一行一行輸出
SequenceFileOutputFormat二進制文件
NullOutputFormat忽略其輸入值
   在WordCount中,我使用的是TextOutputFormat類。最終結果如下。
Beijing	2
China	2
I	2
capital	1
is	1
love	2
of	1
the	1

   到此,本文的內容介紹完了,本文對MapReduce執行框架的組件和執行流程的見解有偏頗之處,請不吝賜教。


   獲取更多幹貨請關注微信公衆號:追夢程序員。

                                                                        



   










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章