shuffle & sort解釋

轉載請標明出處:http://blackwing.iteye.com/blog/1848401

MR任務,充分利用了緩存進行讀寫。

1)map端
每個map任務,都會先把數據寫到一個環形緩存中,該緩存默認大小是100MB,由io.sort.mb(默認值是100MB)和io.sort.spill.percent(默認值是0.8)共同決定。在默認情況下,當緩存達到80MB時,後臺線程就開始把數據spill到磁盤。而map會繼續寫數據到緩存中,當100MB的緩存寫滿後,map就會阻塞,直到spill完成。

在spill寫數據到磁盤前,線程會根據reducer的數量(例如10個reducer)把輸出數據切分爲相應個數的partition,在每個partition中,後臺線程會對其中的數據進行排序,如果該job有combiner,則此時也會調用combiner對數據進行合併。partition是邏輯劃分,是指一個spill的文件中,或邏輯劃分爲幾個partition。

在map結束前,如果有超過min.num.spills.for.combine(默認值3)個spill,則這些spill會被合併成一個分好區的大文件。

每個map生成的數據,會通過http傳輸給reducer。

2)reduce端
reducer通過http把map輸出的數據copy到本地,copy數據的線程數由mapred.reduce.parallel.copies進行設置(默認值5)。

如果map的輸出數據足夠小,則會直接寫入緩存中(由mapred.job.shuffle.input.buffer.percent設置,指佔JVM的比例),否則寫入磁盤。當緩存數據達到mapred.job.shuffle.merge.percent(默認0.8)或者超過mapred.inmem.merge.threshold(默認1000)個文件,則開始把數據spill到磁盤。此時如果job有combiner,則會調用它以減少寫入磁盤的數據。

在數據不斷寫入磁盤同時,後臺線程會把這些數據合併成一個更大的排好序的文件,節省後續合併的時間。當所有map的輸出都copy到reducer後,就進入合併排序階段,生成一個有序的大文件。

總結來說,調用combiner的地方如下:
*map端spill數據到磁盤
*map端,map結束前,合併多個spill
*reduce端spill數據到磁盤

《hadoop in practice》作者的spill過程圖解:
http://grepalex.com/2012/09/24/map-partition-sort-spill/
發佈了62 篇原創文章 · 獲贊 1 · 訪問量 7321
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章