Hadoop(四)——MapReduce

1、輸入分片(Input Split):

在進行map計算之前,mapreduce會根據輸入文件計算輸入分片,每個輸入分片針對一個map任務,輸入分片存儲的並非數據本身,而是一個分片長度和一個記錄數據位置的數據。輸入分片往往和hdfs的block關係密切,假如我們設定hdfs塊的大小是64mb,如果我們輸入三個文件,大小分別是3mb、65mb和127mb,那麼mapreduce會把3mb文件作爲一個輸入分片,65mb分成兩個輸入分片,127mb分成兩個輸入分片。

2、map階段:

3、combiner階段:combiner其實也是一種reduce操作,本地化的預處理,比如簡單合併重複key在值

4、shuffle階段:將map的輸出作爲reduce的輸入的過程就是shuffle。shuffle一開始就是map階段做輸出操作,一般mapreduce計算的都是海量數據,map輸出的時候不可能吧所有文件都放到內存操作,因此map寫入磁盤的過程十分的複雜,更何況map輸出時候要對結果進行排序,內存開銷是 很大的,map在做輸出時候會在內存裏開啓一個緩衝區,默認大小是100mb,並且在配置文件裏爲緩衝區設定了一個閾值,默認是0.8,同時map還會爲輸出操作啓動一個守護線程,如果緩衝區數據達到閾值,守護線程就會把內容寫到磁盤上,這個過程叫做spill,另外20%的內存可以繼續寫入數據,寫入磁盤和寫入內存操作是互不干擾的,如果緩存區被撐爆了,那麼map就會阻塞寫入內存的操作,讓寫入磁盤操作完成後在繼續執行寫入內存操作,寫入磁盤前會有個排序操作,這個實在寫入磁盤操作時候進行,不是在寫入內存時候進行的,如果定義了combiner函數,排序錢還會執行combiner操作。

每次spill操作也就是寫入磁盤操作的時候會寫一個溢出文件,也就是說在坐map輸出有幾次spill就會產生多少個溢出文件,等map輸出全部做完,map會合並這些輸出文件。這個過程裏還會有一個partition操作,其實partition操作和map階段的輸入分片很想,一個partition對應一個reduce作業,partition因此就是reduce的輸入分片,根據實際業務類型或者爲了更好的reduce負載均衡要求進行,合理的partition的設置可以提高reduce的效率。

到了reduce階段就是合併map輸出文件,partitioner會找到對應的map輸出文件,然後進行復制操作,複製操作時reduce會開啓幾個複製線程,默認5個,這個複製過程和map寫入磁盤過程類似,也有閾值和內存大小,複製時候reduce還會進行排序操作和合並文件操作,完事後就會進行reduce計算了。

5.reduce階段:計算完成後,把結果寫入hdfs上

 

map task 讀取數據

map業務處理

對key進行sort排序,grouping分組將相同key的value合併分組輸出,進行一個combiner歸約操作,本地化的reduce預處理,以減小shuffle,reducer的工作量。

reduce task會通過網絡將各個數據收集進行reduce處理,最後將數據保存會輸出,結束job

 

shuffle

shuffle描述着數據從map task 輸出到reduce task輸入的這段過程。

hadoop的集羣環境,大部分的map task和reduce task是執行在不同的節點上的,那麼reduce就要取map的輸出結果。那麼集羣中運行多個job是,task的正常執行會對集羣內部的網絡資源消耗嚴重。雖說這種消耗是正常的,是不可避免的,但是,我們可以採取措施儘可能的減少不必要的網絡資源消耗。另一方面,每個節點的內部,相比於內存,磁盤IO對Job完成時間的影響相當的大。

所以:從以上分析,shuffle過程的基本要求:

1.完整地從map task端拉取數據到reduce task 端

2.在拉取數據的過程中,儘可能地減少網絡資源的消耗

3.儘可能地減少磁盤IO對task執行效率的影響

那麼,shuffle的設計目的就要滿足以下條件:

1.保證拉取數據的完整性

2.儘可能地減少拉取數據的數據量

3.儘可能地使用節點的內存而不是磁盤

一、map階段

map節點執行map task任務生成map的輸出結果

shuffle的工作內容:

從運算效率的出發點,map輸出結果優先存儲在map節點的內存中。每個map task 都有一個內存緩衝區,存儲着map的輸出節點,當緩衝區達到閾值時(0.8),需要講緩衝區中的數據以一個臨時文件的方式存到磁盤(spill),當整個map task結束後再對磁盤中這個map task所產生的所有臨時文件做合併,生成最終的輸出文件。最後,等待reduce task來拉取數據。當然,如果map task的結果不大,能夠完全存儲到內存緩衝區,且未達到內存緩衝區的閾值,那麼就不會有寫臨時文件到磁盤的操作,也不會有後面的合併。

二、reduce階段:

當mapreduce任務提交後,reduce task就不斷通過RPC從JobTracker那裏獲取map task是否完成的信息,如果獲知某臺TaskTracker上的map task執行完成,shuffle的後半段過程就開始啓動。其實呢,reduce task在執行之前的工作就是:不斷的拉取當前job裏每個map task的最終結果,並對不同地方拉取過來的數據不斷地做merge。

reduce階段分三個步驟:

抓取、合併、排序

1、reduce任務會創建並行的抓取線程(fetcher)負責從完成的map任務重獲取結果文件,是否完成通過rpc心跳監聽,通過http協議抓取,默認是5個抓取線程,可調,爲了是整體並行,在map任務量大,分區多的時候,抓取線程調大。

2、抓取拉過來的數據會先保存在內存中,如果內存過大也移除,不可見,不可調,但是單位是每個merge文件,不會切分數據;每個merge文件都會被封裝成一個segment的對象,這個對象控制着這個merge文件的讀取記錄操作。

3、這中segment對象會放到一個內存隊列中MergerQueue,對內存和磁盤上的數據分別進行合併,內存中的merge對應的segment直接合並,磁盤中的合併與一個叫做合併因子的factor有關。

4、排序問題

MergerQueue繼承輪換排序的接口,每一個segment 是排好序的,而且按照key的值大小邏輯(和真的大小沒關係);每一個segment的第一個key都是邏輯最小,而所有的segment的排序是按照第一個key大小排序的,最小的在前面,這種邏輯總能保證第一個segment的第一個key值是所有key的邏輯最小文件合併之後,最終交給reduce函數計算的,是MergeQueue隊列,每次計算的提取數據邏輯都是提取第一個segment的第一個key和value數據,一旦segment被調用了提取key的方法,MergeQueue隊列將會整體重新按照最小key對segment排序,最終形成整體有序的計算結果;

//todo 通過實際操作 繼續理解

 

 

 

 

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