Spark 2.0 在作業(job)完成後花費很長時間結束

1.現象
在監控頁面job運行完成了,但是程序還在運行,要等好久才能結束
2.原因:
spark 2.0 在保存數據的時候  會用 FileOutputCommitter , 問題就出在了 Hadoop 2.0 FileOutputCommitter 實現FileOutputCommitter 裏面有兩個值得注意的方法:commitTask 和 commitJob。在 Hadoop 2.x 的FileOutputCommitter 實現裏面,mapreduce.fileoutputcommitter.algorithm.version 參數控制着 commitTask 和 commitJob 的工作方式。具體代碼如下(爲了說明方便,我去掉了無關緊要的語句,完整代碼可以參見 FileOutputCommitter.java):
可以看到 commitTask 方法裏面,有個條件判斷 algorithmVersion == 1,這個就是 mapreduce.fileoutputcommitter.algorithm.version 參數的值,默認爲1;如果這個參數爲1,那麼在 Task 完成的時候,是將 Task 臨時生成的數據移到 task 的對應目錄下,然後再在 commitJob 的時候移到最終作業輸出目錄,而這個參數,在 Hadoop 2.x 的默認值就是 1!這也就是爲什麼我們看到 job 完成了,但是程序還在移動數據,從而導致整個作業尚未完成,而且最後是由 Spark 的 Driver 執行 commitJob 函數的,所以執行的慢也是有到底的。
而我們可以看到,如果我們將 mapreduce.fileoutputcommitter.algorithm.version 參數的值設置爲 2,那麼在 commitTask 執行的時候,就會調用 mergePaths 方法直接將 Task 生成的數據從 Task 臨時目錄移動到程序最後生成目錄。而在執行 commitJob 的時候,直接就不用移動數據了,自然會比默認的值要快很多
注意,其實在 Hadoop 2.7.0 之前版本,我們可以將 mapreduce.fileoutputcommitter.algorithm.version 參數設置爲非1的值就可以實現這個目的,因爲程序裏面並沒有限制這個值一定爲2,。不過到了 Hadoop 2.7.0,mapreduce.fileoutputcommitter.algorithm.version 參數的值必須爲1或2,具體參見 MAPREDUCE-4815。
3.最終解決:
spark.conf.set("mapreduce.fileoutputcommitter.algorithm.version", "2") 
本人在阿里雲上用的
到此問題就結束了
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章