spark shuffer調優

性能優化 shuffle

spark.shuffle.file.buffer,默認32k
spark.shuffle.memoryFraction,0.2

map端內存緩衝,reduce端內存佔比;很多資料、網上視頻,都會說,這兩個參數,
是調節shuffle性能的不二選擇,很有效果的樣子,實際上,不是這樣的。

以實際的生產經驗來說,這兩個參數沒有那麼重要,往往來說,shuffle的性能不是因爲
這方面的原因導致的

但是,有一點點效果的,broadcast,數據本地化等待時長;這兩個shuffle調優的小點,
其實也是需要跟其他的大量的小點配合起來使用,一點一點的提升性能,最終很多個性能
調優的小點的效果,彙集在一起之後,那麼就會有可以看見的還算不錯的性能調優的效果。

默認情況下,shuffle的map task,輸出到磁盤文件的時候,統一都會先寫入每個task自己
關聯的一個內存緩衝區。

這個緩衝區大小,默認是32kb。

每一次,當內存緩衝區滿溢之後,纔會進行spill操作,溢寫操作,溢寫到磁盤文件中去

reduce端task,在拉取到數據之後,會用hashmap的數據格式,來對各個key對應的values進行匯聚。

針對每個key對應的values,執行我們自定義的聚合函數的代碼,比如_ + _(把所有values累加起來)

reduce task,在進行匯聚、聚合等操作的時候,實際上,使用的就是自己對應的executor的內存,
executor(jvm進程,堆),默認executor內存中劃分給reduce task進行聚合的比例,是0.2。

問題來了,因爲比例是0.2,所以,理論上,很有可能會出現,拉取過來的數據很多,那麼在內存中,
放不下;這個時候,默認的行爲,就是說,將在內存放不下的數據,都spill(溢寫)到磁盤文件中去。

原理說完之後,來看一下,默認情況下,不調優,可能會出現什麼樣的問題?

默認,map端內存緩衝是每個task,32kb。
默認,reduce端聚合內存比例,是0.2,也就是20%。

如果map端的task,處理的數據量比較大,但是呢,你的內存緩衝大小是固定的。
可能會出現什麼樣的情況?

每個task就處理320kb,32kb,總共會向磁盤溢寫320 / 32 = 10次。
每個task處理32000kb,32kb,總共會向磁盤溢寫32000 / 32 = 1000次。

在map task處理的數據量比較大的情況下,而你的task的內存緩衝默認是比較小的,32kb。
可能會造成多次的map端往磁盤文件的spill溢寫操作,發生大量的磁盤IO,從而降低性能。

reduce端聚合內存,佔比。默認是0.2。如果數據量比較大,reduce task拉取過來的數據很多,
那麼就會頻繁發生reduce端聚合內存不夠用,頻繁發生spill操作,溢寫到磁盤上去。而且最要命的是,
磁盤上溢寫的數據量越大,後面在進行聚合操作的時候,很可能會多次讀取磁盤中的數據,進行聚合。

默認不調優,在數據量比較大的情況下,可能頻繁地發生reduce端的磁盤文件的讀寫。

這兩個點之所以放在一起講,是因爲他們倆是有關聯的。數據量變大,map端肯定會出點問題;
reduce端肯定也會出點問題;出的問題是一樣的,都是磁盤IO頻繁,變多,影響性能。

調優:

調節map task內存緩衝:spark.shuffle.file.buffer,默認32k(spark 1.3.x不是這個參數,
後面還有一個後綴,kb;spark 1.5.x以後,變了,就是現在這個參數)
調節reduce端聚合內存佔比:spark.shuffle.memoryFraction,0.2

在實際生產環境中,我們在什麼時候來調節兩個參數?

看Spark UI,如果你的公司是決定採用standalone模式,那麼很簡單,你的spark跑起來,
會顯示一個Spark UI的地址,4040的端口,進去看,依次點擊進去,可以看到,你的每個stage的詳情,
有哪些executor,有哪些task,每個task的shuffle write和shuffle read的量,shuffle的磁盤和內存,
讀寫的數據量;如果是用的yarn模式來提交,課程最前面,從yarn的界面進去,點擊對應的application,
進入Spark UI,查看詳情。

如果發現shuffle 磁盤的write和read,很大。這個時候,就意味着最好調節一些shuffle的參數。
進行調優。首先當然是考慮開啓map端輸出文件合併機制。

調節上面說的那兩個參數。調節的時候的原則。spark.shuffle.file.buffer,每次擴大一倍,
然後看看效果,64,128;spark.shuffle.memoryFraction,每次提高0.1,看看效果。

不能調節的太大,太大了以後過猶不及,因爲內存資源是有限的,你這裏調節的太大了,
其他環節的內存使用就會有問題了。

調節了以後,效果?map task內存緩衝變大了,減少spill到磁盤文件的次數;reduce端聚合內存變大了,
減少spill到磁盤的次數,而且減少了後面聚合讀取磁盤文件的數量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章