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