1. 程式人生 > >spark調優-JVM調優+Shuffle調優

spark調優-JVM調優+Shuffle調優

          JVM調優:

1 降低cache操作的記憶體佔比

       spark中,堆記憶體又被劃分成了兩塊,一塊是專門用來給RDD的cache、persist操作進行RDD資料快取用的。另外一塊用來給spark運算元函式的執行使用的,存放函式中自己建立的物件。

預設情況下,給RDD cache操作的記憶體佔比,是0.6,60%的記憶體都給了cache操作了。但是問題是,如果某些情況下cache不是那麼的緊張,問題在於task運算元函式中建立的物件過多,然後記憶體又不太大,導致了頻繁的minor gc,甚至頻繁full gc,導致spark頻繁的停止工作。效能影響會很大。

2 調節executor堆外記憶體與連線等待時長

調節executor堆外記憶體

       有時候,如果你的spark作業處理的資料量特別大,幾億資料量。然後spark作業一執行,時不時的報錯,shuffle file cannot find,executor、task lost,out of memory(記憶體溢位)。可能是executor的堆外記憶體不太夠用,導致executor在執行的過程中,可能會記憶體溢位,可能導致後續的stage的task在執行的時候,要從一些executor中去拉取shuffle map output檔案,但是executor可能已經掛掉了,關聯的block manager也沒有了。所以會報shuffle output file not found,resubmitting task,executor lost。spark作業徹底崩潰。上述情況下,就可以去考慮調節一下executor的堆外記憶體。也許就可以避免報錯。此外,有時堆外記憶體調節的比較大的時候,對於效能來說,也會帶來一定的提升。

可以調節堆外記憶體的上限:

--conf spark.yarn.executor.memoryOverhead=2048

調節連線等待時長

我們知道,executor會優先從自己本地關聯的BlockManager中獲取某份資料。如果本地block manager沒有的話,那麼會通過TransferService,去遠端連線其他節點上executor的block manager去獲取。

而此時上面executor去遠端連線的那個executor,因為task建立的物件特別大,特別多,

頻繁的讓JVM堆記憶體滿溢,正在進行垃圾回收。而處於垃圾回收過程中,所有的工作執行緒全部停止,相當於只要一旦進行垃圾回收,spark / executor停止工作,無法提供響應。

此時呢,就會沒有響應,無法建立網路連線,會卡住。spark預設的網路連線的超時時長,是60s,如果卡住60s都無法建立連線的話,那麼就宣告失敗了。

報錯幾次,幾次都拉取不到資料的話,可能會導致spark作業的崩潰。也可能會導致DAGScheduler,反覆提交幾次stage。TaskScheduler反覆提交幾次task。大大延長我們的spark作業的執行時間。

可以考慮調節連線的超時時長:

--conf spark.core.connection.ack.wait.timeout=300

Shuffle調優

1 合併map端輸出檔案,方法:開啟shuffle map端輸出檔案合併機制

new SparkConf().set("spark.shuffle.consolidateFiles", "true")

預設情況下,是不開啟的,就是會發生如上所述的大量map端輸出檔案的操作,嚴重影響效能。

2 調節map端記憶體緩衝與reduce端記憶體佔比

預設reduce佔比0.2  map站0.8,大家想想看如果reduce拉去過來的資料很大,記憶體很小,一次讀不完,只能快取到磁碟,然後再去磁碟讀,產生大量IO消耗,所以可以調節reduce的記憶體佔比,把map的shuffle溢寫32k調大

調節map task記憶體緩衝:spark.shuffle.file.buffer,預設32k(spark 1.3.x不是這個引數,後面還有一個字尾,kb。spark 1.5.x以後,變了,就是現在這個引數)

調節reduce端聚合記憶體佔比:spark.shuffle.memoryFraction,0.2

3 合理使用hashshuffleManager(spark1.2之前預設的)跟sortShuffleManager(spark1.2之後預設的)

3.1、需不需要資料預設就讓spark給你進行排序?就好像mapreduce,預設就是有按照key的排序。如果不需要的話,其實還是建議搭建就使用最基本的HashShuffleManager,因為最開始就是考慮的是不排序,換取高效能。

3.2、什麼時候需要用sort shuffle manager?如果你需要你的那些資料按key排序了,那麼就選擇這種吧,而且要注意,reduce task的數量應該是超過200的,這樣sort、merge(多個檔案合併成一個)的機制,才能生效把。但是這裡要注意,你一定要自己考量一下,有沒有必要在shuffle的過程中,就做這個事情,畢竟對效能是有影響的。

3.3、如果你想選用sort based shuffle manager,而且你們公司的spark版本比較高,是1.5.x版本的,那麼可以考慮去嘗試使用tungsten-sort shuffle manager。看看效能的提升與穩定性怎麼樣。

總結:

-->   如果你不想要你的資料在shuffle時排序,那麼就自己設定一下,用hash shuffle manager。

-->   如果你的確是需要你的資料在shuffle時進行排序的,那麼就預設不用動,預設就是sort shuffle manager。或者是什麼?如果你壓根兒不care是否排序這個事兒,那麼就預設讓他就是sort的。調節一些其他的引數(consolidation機制)。(80%,都是用這種)