1. 程式人生 > >spark效能調優(四)調節堆外記憶體和等待時長

spark效能調優(四)調節堆外記憶體和等待時長

調節堆外記憶體!!!


executor堆外記憶體


spark底層shuffle使用netty傳輸,所以使用了堆外記憶體!1.2之前是NIO就是socket,之後預設使用netty


有時候,如果你的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的堆外記憶體。也許就可以避免報錯;此外,有時,
堆外記憶體調節的比較大的時候,對於效能來說,也會帶來一定的提升。


這個executor跑著跑著,突然記憶體不足了,堆外記憶體不足了,可能會OOM,掛掉。block manager也沒有了,
資料也丟失掉了。


如果此時,stage0的executor掛了,block manager也沒有了;此時,stage1的executor的task,雖然通過
Driver的MapOutputTrakcer獲取到了自己資料的地址;但是實際上去找對方的block manager獲取資料的
時候,是獲取不到的


此時,就會在spark-submit執行作業(jar),client(standalone client、yarn client),
在本機就會打印出log


shuffle output file not found。。。
DAGScheduler,resubmitting task,一直會掛掉。反覆掛掉幾次,反覆報錯幾次


整個spark作業就崩潰了


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


spark-submit腳本里面,去用--conf的方式,去新增配置;一定要注意!!!切記,
不是在你的spark作業程式碼中,用new SparkConf().set()這種方式去設定,不要這樣去設定,是沒有用的!
一定要在spark-submit指令碼中去設定。


spark.yarn.executor.memoryOverhead(看名字,顧名思義,針對的是基於yarn的提交模式)


預設情況下,這個堆外記憶體上限大概是300多M;後來我們通常專案中,真正處理大資料的時候,
這裡都會出現問題,導致spark作業反覆崩潰,無法執行;此時就會去調節這個引數,到至少1G(1024M),
甚至說2G、4G


通常這個引數調節上去以後,就會避免掉某些JVM OOM的異常問題,同時呢,會讓整體spark作業的效能,
得到較大的提升。






調節等待時長!!!


executor,優先從自己本地關聯的BlockManager中獲取某份資料


如果本地block manager沒有的話,那麼會通過TransferService,去遠端連線其他節點上executor
的block manager去獲取


嘗試建立遠端的網路連線,並且去拉取資料
task建立的物件特別大,特別多


頻繁的讓JVM堆記憶體滿溢,進行垃圾回收。
正好碰到那個exeuctor的JVM在垃圾回收


JVM調優:垃圾回收


處於垃圾回收過程中,所有的工作執行緒全部停止;相當於只要一旦進行垃圾回收,
spark / executor停止工作,無法提供響應


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


碰到一種情況,偶爾,偶爾,偶爾!!!沒有規律!!!某某file。一串file id。
uuid(dsfsfd-2342vs--sdf--sdfsd)。not found。file lost。


這種情況下,很有可能是有那份資料的executor在jvm gc。所以拉取資料的時候,建立不了連線。
然後超過預設60s以後,直接宣告失敗。


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


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


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


spark-submit指令碼,切記,不是在new SparkConf().set()這種方式來設定的。


spark.core.connection.ack.wait.timeout(spark core,connection,連線,ack,wait timeout,
建立不上連線的時候,超時等待時長)


調節這個值比較大以後,通常來說,可以避免部分的偶爾出現的某某檔案拉取失敗,某某檔案lost掉了。。。


為什麼在這裡講這兩個引數呢?


因為比較實用,在真正處理大資料(不是幾千萬資料量、幾百萬資料量),幾億,幾十億,幾百億的時候。
很容易碰到executor堆外記憶體,以及gc引起的連線超時的問題。
file not found,executor lost,task lost。


調節上面兩個引數,還是很有幫助的。