2017-10-19 135 views
2

我正在運行處理多組數據點的Spark應用程序;其中一些組需要按順序處理。當運行應用程序的小數據點(約100),一切正常。但在某些情況下,這些套件的尺寸大約爲ca。 10,000個數據點,這些會導致工作與以下堆棧跟蹤崩潰:Spark worker在臨時洗牌文件上拋出FileNotFoundException

Exception in thread "main" org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 26.0 failed 4 times, most recent failure: Lost task 0.3 in stage 26.0 (TID 36, 10.40.98.10, executor 1): java.io.FileNotFoundException: /tmp/spark-5198d746-6501-4c4d-bb1c-82479d5fd48f/executor-a1d76cc1-a3eb-4147-b73b-29742cfd652d/blockmgr-d2c5371b-1860-4d8b-89ce-0b60a79fa394/3a/temp_shuffle_94d136c9-4dc4-439e-90bc-58b18742011c (No such file or directory) 
    at java.io.FileOutputStream.open0(Native Method) 
    at java.io.FileOutputStream.open(FileOutputStream.java:270) 
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213) 
    at org.apache.spark.storage.DiskBlockObjectWriter.initialize(DiskBlockObjectWriter.scala:102) 
    at org.apache.spark.storage.DiskBlockObjectWriter.open(DiskBlockObjectWriter.scala:115) 
    at org.apache.spark.storage.DiskBlockObjectWriter.write(DiskBlockObjectWriter.scala:235) 
    at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:151) 
    at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:96) 
    at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:53) 
    at org.apache.spark.scheduler.Task.run(Task.scala:108) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:335) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
    at java.lang.Thread.run(Thread.java:748) 

我已經檢查這個錯誤的多個實例,畢竟日誌文件,但沒有發現任何其他錯誤消息。

搜索這個問題的互聯網,我發現,似乎並不適用於我的情況兩個潛在原因:

  • 運行星火過程中的用戶沒有在/tmp/讀/寫權限目錄。
    • 由於只發生大數據集(而不是總是)的錯誤,我不認爲這是問題所在。
  • /tmp/目錄沒有足夠的空間用於洗牌文件(或其他臨時Spark文件)。
    • 我的系統上的/tmp/目錄大約有45GB可用,單個數據點中的數據量(< 1KB)意味着這也可能不是這種情況。

我一直在揮舞着這個問題了幾個小時,試圖找到變通辦法和可能的原因。

  • 我試圖減少集羣(通常是兩臺機器)到單個工人,與驅動程序在同一臺機器上運行,希望這可以消除對洗牌的需要,從而防止出現此錯誤。這沒有用;錯誤以完全相同的方式發生。
  • 我已經將問題隔離到通過尾遞歸方法按順序處理數據集的操作。

是什麼導致了這個問題?我該如何去確定自己的原因?

回答

2

問題原來是工作人員發生堆棧溢出(ha!)。

在預感上,我重寫了完全在驅動程序上執行的操作(有效地禁用Spark功能)。當我運行此代碼時,系統仍然崩潰,但現在顯示StackOverflowError。與我以前認爲的相反,顯然尾遞歸方法肯定會導致堆棧溢出,就像任何其他形式的遞歸一樣。重寫該方法後不再使用遞歸,問題消失。

堆棧溢出可能不是唯一可以產生原始FileNotFoundException的問題,但做出臨時代碼更改將操作提供給驅動程序似乎是確定問題實際原因的好方法。