0基礎學大資料好學嗎怎麼學?看MapReduce工作流程

weixin_34214500發表於2017-05-10

大資料0基礎的夥伴們,科多大資料來帶你們看看MapReduce的工作流程。

5875695-bcf0d9143ed1067d.png

MapReduce特點

整體結構

5875695-1441c9942598bb08.png

Hadoop工作架構

我們的應用程式通過Hadoop job client向Hadoop叢集提交作業,Hadoop叢集中Master節點負責排程各個Slave節點共同完成作業。

Hadoop job client是什麼?

我認為有2個含義。1是在程式碼中使用的api,2是提交作業時使用的命令列工具。

比如在參考文章中的WordCount v1.0原始碼,main方法負責構建配置並提交作業:

public static void main(String[] args) throws Exception {

Configuration conf = new Configuration();

Job job = Job.getInstance(conf, "word count");

job.setJarByClass(WordCount.class);

job.setMapperClass(TokenizerMapper.class);

job.setCombinerClass(IntSumReducer.class);

job.setReducerClass(IntSumReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job, new Path(args[0]));

FileOutputFormat.setOutputPath(job, new Path(args[1]));

System.exit(job.waitForCompletion(true) ? 0 : 1);

}

這裡大部分的類都來自包org.apache.hadoop.mapreduce。

而在執行這個程式的時候,先生成jar包,再執行下面的命令:

$ bin/hadoop jar wc.jar WordCount /user/joe/wordcount/input /user/joe/wordcount/output

我們需要提供什麼

5875695-2b5cb64c71fb0054.png

1.提供input locations和output location

這個是在執行jar包的命令列中提供的.

2.提供map和reduce的實現

這個對應原始碼中的TokenizerMapper和IntSumReducer類。

3.提供job引數

具體對應原始碼中的main方法.

包括上面的input/output locations, map和reduce的實現, 都需要以job引數的形式來提供, 才能實際被使用.

流程細節

flat

5875695-d93c5e62ac70bd18.png

流水細節

client將軟體和資料提交給job,job將輸入拆分成一個個獨立的資料塊,每個資料塊提交給不同的map task來處理.

結合HDFS的內容,我推論實際的過程是這樣子的:

. job查詢NameNode後設資料,得知輸入資料檔案對應的資料塊及其所在的DataNode位置.

.然後將所要執行的軟體,和對應的資料塊的後設資料資訊傳給對應的DataNode.

.每個DataNode所接收到的軟體是一樣的,但是資料塊的後設資料資訊就只是自己相關的那一部分.

. DataNode接收軟體和資料塊後設資料之後,就找出對應的資料,作為輸入來執行軟體.

map對資料塊中的資料進行初次處理,由於每個map task處理的是不同的資料塊,所以這裡是並行的. 處理完之後輸出形式的中間結果.

框架對中間結果進行處理,對每個中間結果進行排序,分割槽,發到具體的reduce task,然後再進行排序,分組.

最後reduce程式接收到的輸入是>的格式,這是按照key進行分組的結果.

reduce負責處理>, 並輸出最終的結果到輸出目錄.

整個過程的資料型別變化情況

(input) -> map -> -> shuffle & sort -> > -> reduce -> (output)

map和reduce的個數

map task的個數 = input檔案的所有的塊的個數.

reduce task的個數可以設定:Job.setNumReduceTasks();設定的大, 會增加框架開銷, 但是可以增加負載均衡 並降低故障成本(每一個reduce負責的內容少了). 設定的小則會有相反的結論.

5875695-b46e8e53098e2cf2.png

分割槽和reduce個數

group

5875695-bdd7abed4c553100.png

MapReduce的細節

淺綠色背景是我們要做的,其他是框架做的.

Map

• map 是我們定義的map函式, 負責從我們指定的輸入中解析出作為中間結果的

• sort 負責對map的結果進行排序

• partition 負責對上一步的結果資料進行分割槽.不同的分割槽會發到不同的Reduce task.

• combine 負責本地聚合資料,這樣可以減少發到Reduce task的資料量. 由我們自己定義聚合函式,這一步不是必須的.

Reduce

• shuffle 通過HTTP接收分割槽資料

• sort 對分割槽資料排序, 分組(考慮到不同Map發來的分割槽,可能有相同的key)

• reduce 產生最終結果

結合WordCount v1.0看流程

這裡結合WordCount v1.0執行過程來對工作流程中每一步的工作有個形象的瞭解.

5875695-b243cb8053c94465.png

demo處理過程

WordCount負責統計輸入檔案中每個單詞的出現次數.

input有2個檔案, 每個檔案佔據一個資料塊(每個檔案都那麼小), 所以會有2個map task分別處理一個資料塊.

map的結果是以此記錄哪個單詞出現了一次, 並沒有進行排序和聚合處理.

map到combine之間還有一段, 就是框架對資料進行了排序, combine接收到的已經是排序的結果.

combine負責在本地聚合, 它主要可以減少資料從map到reduce的傳輸量. 可以看到combine的輸出已經是排好序且做了聚合處理.

reduce負責對接收到的來自2個map的資料塊進行再分組, 排序, 聚合. 並最終輸出結果.

相關文章