1. 程式人生 > 其它 >MapReduce的shuffle階段

MapReduce的shuffle階段

可以先檢視其它博主

https://blog.csdn.net/weixin_44318830/article/details/103061572

這是另一個博主的

https://blog.csdn.net/weixin_52346300/article/details/116021803?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-8.pc_relevant_default&spm=1001.2101.3001.4242.5&utm_relevant_index=11

解剖環形緩衝區

環形緩衝區分為三塊,空閒區、資料區、索引區。初始位置取名叫做“赤道”,就是圓環上的白線那個位置。初始狀態的時候,資料和索引都為0,所有空間都是空閒狀態。

tips:這裡有一個調優引數,可以設定環形緩衝區的大小:

mapreduce.task.io.sort.mb,預設100M,可以稍微設定大一些,但不要太大,因為每個spilt就128M。

環形緩衝區寫入的時候,有個細節:資料是從赤道的右邊開始寫入,索引(每次申請4kb)是從赤道是左邊開始寫。這個設計很有意思,這樣兩個檔案各是各的,互不干涉。

在資料和索引的大小到了mapreduce.map.sort.spill.percent引數設定的比例時(預設80%,這個是調優的引數),會有兩個動作:

1、對寫入的資料進行原地排序,並把排序好的資料和索引spill到磁碟上去;

2、在空閒的20%區域中,重新算一個新的赤道,然後在新赤道的右邊寫入資料,左邊寫入索引;

3、當20%寫滿了,但是上一次80%的資料還沒寫到磁碟的時候,程式就會panding一下,等80%空間騰出來之後再繼續寫。

如此迴圈往復,永不停歇,直到所有任務全部結束。整個操作都在記憶體,形狀像一個環,所以才叫環形緩衝區。

為什麼要有環形緩衝區?

我們讀取到檔案,直接排序,然後寫到HDFS裡不就好了嗎?為啥還要整一個環形緩衝區呢?

那從架構的角度看環形緩衝區,他這麼設計有什麼用呢?解決什麼問題呢?

思路廣的朋友應該已經反應過來了。環形緩衝區不需要重新申請新的記憶體,始終用的都是這個記憶體空間。大家知道MR是用java寫的,而Java有一個最討厭的機制就是Full GC。Full GC總是會出來搗亂,這個bug也非常隱蔽,發現了也不好處理。環形緩衝區從頭到尾都在用那一個記憶體,不斷重複利用,因此完美的規避了Full GC導致的各種問題,同時也規避了頻繁申請記憶體引發的其他問題。

另外呢,環形緩衝區同時做了兩件事情:1、排序;2、索引。在這裡一次排序,將無序的資料變為有序,寫磁碟的時候順序寫,讀資料的時候順序讀,效率高非常多!

在這裡設定索引區也是為了能夠持續的處理任務。每讀取一段資料,就往索引檔案裡也寫一段,這樣在排序的時候能加快速度。