spark任務在執行期間,有時候會遇到臨時目錄創建失敗,導致任務執行錯誤。
java.io.IOException: Failed to create local dir in ……
spark執行過程的文件夾
- spark創建臨時文件機制
spark作為並行計算框架,同一個作業會被划分為多個任務在多個節點執行,reduce的輸入可能存在於多個節點,因此需要shuffle將所有reduce的輸入匯總起來;而shuffle時需要通過diskBlockManage將map結果寫入本地,優先寫入memory store,在memore store空間不足時會創建臨時文件。 - 臨時文件夾配置
memory store的大小取決於spark.excutor.memory參數,默認為spark.excutor.memory*0.6;可通過spark.env中添加配置SPARK_LOCAL_DIRS或程序中設定spark.local.dir,可配置多個路徑,逗號分隔增強io效率。
SPARK_LOCAL_DIRS:
Directory to use for "scratch" space in Spark, including map output files and RDDs that get stored on disk.
This should be on a fast, local disk in your system.
It can also be a comma-separated list of multiple directories on different disks.
原因分析
常見原因包括
- 臨時目錄文件過多導致,當一個spark任務執行失敗時,之前創建的臨時文件不會被刪除,就會殘留下來,spark任務失敗次數越多,就越可能導致臨時目錄故障。
- 磁盤空間、inode資源、權限(比如巡檢項修改)等
主要排查手段
進入臨時目錄,查看下臨時目錄當前狀況,嘗試手動創建是否ok。
-
磁盤空間問題。
排查:磁盤空間不足,或者磁盤掉載;通過df -h
、du -sh
或者fdisk
查詢磁盤空間。
解決:刪除舊文件釋放空間;或者掛載新盤。 -
目錄權限不對。
排查:進入spark.local.dir臨時目錄,查詢權限。
解決:修改成正確權限。 -
臨時目錄文件過多。
在spark.local.dir手動創建臨時目錄時,報錯Too many links……
,
排查:查詢文件目錄下是否文件/目錄個數超限,ll | wc -l
解決:刪除舊文件釋放空間;或者掛載新盤。linux ext2/ext3單個目錄下子目錄+文件個數不能超過32000,除去默認子目錄當前目錄(.)和上級目錄(..)之外,一個目錄下最多能創建31998個(子目錄+文件)。而ext4系統無此限制。可以通過命令df -lhT查詢。 include/linux/ext2_fs.h:#define EXT2_LINK_MAX 32000 include/linux/ext3_fs.h:#define EXT3_LINK_MAX 32000
-
inode資源不足
排查:查詢磁盤inode資源使用,df -i
解決:刪除舊文件釋放空間;或者掛載新盤。