在早期版本的Spark中,shuffle過程沒有磁盤讀寫操做,是純內存操做,後來發現效率較低,且極易引起OOME,較新版本的Shuffle操做都加入了磁盤讀寫進行了改進。
一、未經優化的HashShuffleManager:上一個stage中每個task會對下一個stage的每個task寫一份數據文件,假定上一個stage有N個task,下一個stage有M個task,此時由上到下造成N個1對M的映射關係,總共產生【N M】個文件。這種方式的優勢是思路簡單,數據文件的邏輯隔離性更強。缺點是在磁盤上產生的文件個數太多,每一個文件的讀寫都須要創建管道等操做,過多的文件勢必增長額外的開銷,效率較低。【同將多個小文件打包爲一個大文件再拷貝,比直接拷貝多個小文件更快,一個道理】
二、優化過的HashShuffleManager:上一個stage中每個task共同寫下一個stage的每個task獨有的數據文件,假定上一個stage有N個task,下一個stage有M個task,此時由上到下造成M個N對1的映射關係,總共產生M個文件(文件數量只取決於下一個stage的task數量)。因爲文件數量的減小,性能獲得了必定的提高。
**
三、SortShuffleManager:這是當前版本中使用的方式,進一步減小數據文件個數,階段之間只經過2個文件來傳遞數據【索引文件、數據文件】。在上一個階段中,每一個task都將數據在內存中進行排序生成文件(若是內存不夠用就溢寫到磁盤),將多個排序後的文件合併到同一個數據文件中,配合索引文件,下游task就能高效的完成讀取操做。
因爲排序操做是一個相對低效的操做,因此在小數據量時可使用Hash算法來達到快速定位的目的。此時就輪到bypass機制,其內容是當shuffle-map-task數量小於bypassMergeThreshold(默認200個)時或者不是聚合類shuffle,就不採用排序而換爲Hash操做。算法