hadoop作業reduce過程調優使用到的參數筆記

 

reduce的運行是分成三個階段的。分別爲copy->sort->reduce。

由於job的每一個map都會根據reduce(n)數將數據分成map 輸出結果分成n個partition,

所以map的中間結果中是有可能包含每一個reduce需要處理的部分數據的。

所以,爲了優化reduce的執行時間,hadoop中是等job的第一個map結束後,

所有的reduce就開始嘗試從完成的map中下載該reduce對應的partition部分數據。

這個過程就是通常所說的shuffle,也就是copy過程。

 

參數:mapred.reduce.parallel.copies(default 5)

說明:每個reduce並行下載map結果的最大線程數

Reduce task在做shuffle時,實際上就是從不同的已經完成的map上去下載屬於自己這個reduce的部分數據,

由於map通常有許多個,所以對一個reduce來說,下載也可以是並行的從多個map下載,這個並行度是可以調整的,

調整參數爲:mapred.reduce.parallel.copies(default 5)。

默認情況下,每個只會有5個並行的下載線程在從map下數據,如果一個時間段內job完成的map有100個或者更多,

那麼reduce也最多隻能同時下載5個map的數據,

所以這個參數比較適合map很多並且完成的比較快的job的情況下調大,有利於reduce更快的獲取屬於自己部分的數據。

 

參數:mapred.reduce.copy.backoff(default 300秒)

說明:reduce下載線程最大等待時間(秒)

reduce的每一個下載線程在下載某個map數據的時候,有可能因爲那個map中間結果所在機器發生錯誤,

或者中間結果的文件丟失,或者網絡瞬斷等等情況,這樣reduce的下載就有可能失敗,

所以reduce的下載線程並不會無休止的等待下去,當一定時間後下載仍然失敗,那麼下載線程就會放棄這次下載,

並在隨後嘗試從另外的地方下載(因爲這段時間map可能重跑)。

所以reduce下載線程的這個最大的下載時間段是可以調整的,

調整參數爲:mapred.reduce.copy.backoff(default 300秒)。

如果集羣環境的網絡本身是瓶頸,那麼用戶可以通過調大這個參數來避免reduce下載線程被誤判爲失敗的情況。

不過在網絡環境比較好的情況下,沒有必要調整。通常來說專業的集羣網絡不應該有太大問題,所以這個參數需要調整的情況不多。

 

參數:io.sort.factor

Reduce將map結果下載到本地時,同樣也是需要進行merge的,所以io.sort.factor的配置選項同樣會影響reduce進行merge時的行爲,

該參數的詳細介紹上文已經提到,當發現reduce在shuffle階段iowait非常的高的時候,就有可能通過調大這個參數來加大一次merge時的併發吞吐,優化reduce效率。

 

參數:mapred.job.shuffle.input.buffer.percent(default 0.7)

說明:用來緩存shuffle數據的reduce task heap百分比

Reduce在shuffle階段對下載來的map數據,並不是立刻就寫入磁盤的,而是會先緩存在內存中,然後當使用內存達到一定量的時候才刷入磁盤。

這個內存大小的控制就不像map一樣可以通過io.sort.mb來設定了,而是通過另外一個參數來設置:mapred.job.shuffle.input.buffer.percent(default 0.7),

這個參數其實是一個百分比,意思是說,shuffile在reduce內存中的數據最多使用內存量爲:0.7 × maxHeap of reduce task。

也就是說,如果該reduce task的最大heap使用量(通常通過mapred.child.java.opts來設置,比如設置爲-Xmx1024m)的一定比例用來緩存數據。

默認情況下,reduce會使用其heapsize的70%來在內存中緩存數據。

如果reduce的heap由於業務原因調整的比較大,相應的緩存大小也會變大,這也是爲什麼reduce用來做緩存的參數是一個百分比,而不是一個固定的值了。

 

參數:mapred.job.shuffle.merge.percent(default 0.66)

說明:緩存的內存中多少百分比後開始做merge操作

假設mapred.job.shuffle.input.buffer.percent爲0.7,reduce task的max heapsize爲1G,

那麼用來做下載數據緩存的內存就爲大概700MB左右,這700M的內存,跟map端一樣,

也不是要等到全部寫滿纔會往磁盤刷的,而是當這700M中被使用到了一定的限度(通常是一個百分比),就會開始往磁盤刷。

這個限度閾值也是可以通過job參數來設定的,設定參數爲:mapred.job.shuffle.merge.percent(default 0.66)。

如果下載速度很快,很容易就把內存緩存撐大,那麼調整一下這個參數有可能會對reduce的性能有所幫助。

 

參數:mapred.job.reduce.input.buffer.percent(default 0.0)

說明:sort完成後reduce計算階段用來緩解數據的百分比

當reduce將所有的map上對應自己partition的數據下載完成後,就會開始真正的reduce計算階段

(中間有個sort階段通常時間非常短,幾秒鐘就完成了,因爲整個下載階段就已經是邊下載邊sort,然後邊merge的)。

當reduce task真正進入reduce函數的計算階段的時候,有一個參數也是可以調整reduce的計算行爲。

也就是:mapred.job.reduce.input.buffer.percent(default 0.0)。

由於reduce計算時肯定也是需要消耗內存的,而在讀取reduce需要的數據時,同樣是需要內存作爲buffer,

這個參數是控制,需要多少的內存百分比來作爲reduce讀已經sort好的數據的buffer百分比。

默認情況下爲0,也就是說,默認情況下,reduce是全部從磁盤開始讀處理數據。

如果這個參數大於0,那麼就會有一定量的數據被緩存在內存並輸送給reduce,

當reduce計算邏輯消耗內存很小時,可以分一部分內存用來緩存數據,反正reduce的內存閒着也是閒着。

發佈了127 篇原創文章 · 獲贊 76 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章