Apache Spark技術實戰之8:Standalone部署模式下的臨時文件清理


未經本人同意嚴禁轉載,徽滬一郎。

概要

在Standalone部署模式下,Spark運行過程中會創建哪些臨時性目錄及文件,這些臨時目錄和文件又是在什么時候被清理,本文將就這些問題做深入細致的解答。

從資源使用的方面來看,一個進程運行期間會利用到這四個方面的資源,分別是CPU,內存,磁盤和網絡。進程退出之后,CPU,內存和網絡都會由操作系統負責釋放掉,但是運行過程中產生臨時文件如果進程自己不在退出之前有效清除,就會留下一地雞毛,浪費有效的存儲空間。

部署時的第三方依賴

再提出具體的疑問之前,先回顧一下standalone的部署模式

在standalone下又分為client模式和cluster模式,其中client模式下,driver和client運行於同一JVM中,不由worker啟動,該JVM進程直到spark application計算完成返回結果后才退出。如下圖所示。

而在cluster模式下,driver由worker啟動,client在確認spark application成功提交給cluster后直接退出,並不等待spark application運行結果返回。如下圖所示

 

從部署圖來進行分析,每個JVM進程在啟動時的文件依賴如何得到滿足。

  1. Master進程最為簡單,除了spark jar包之外,不存在第三方庫依賴
  2. Driver和Executor在運行的時候都有可能存在第三方包依賴,分開來講
    1. Driver比較簡單,spark-submit在提交的時候會指定所要依賴的jar文件從哪里讀取
    2. Executor由worker來啟動,worker需要下載Executor啟動時所需要的jar文件,那么從哪里下載呢。

為了解決Executor啟動時依賴的Jar問題,Driver在啟動的時候要啟動HttpFileServer存儲第三方jar包,然后由worker從HttpFileServer來獲取。為此HttpFileServer需要創建相應的目錄,而Worker也需要創建相應的目錄。

HttpFileServer創建目錄的過程詳見於SparkEnv.scala中create函數。

spark會為每一個提交的application生成一個文件夾,默認位於$SPARK_HOME/work目錄下,用以存放從HttpFileServer下載下來的第三方庫依賴及Executor運行時生成的日志信息。

實驗1

運行spark-shell,查看在/tmp目錄下會新產生哪些目錄。

#$SPARK_HOME/bin/spark-shell

在/tmp目錄下會新增四個與spark-shell相關的文件夾

spark+隨機數目錄

  分別用於driver本身,driver創建的tmp目錄,httpfileserver創建的目錄

spark-local目錄

  用以存放executor執行過程中生成的shuffle output和cache的內容

運行中的臨時文件

Executor在運行的時候,會生成Shuffle Output,如果對RDD進行Cache的話,還有可能會將RDD的內容吐到磁盤中。這些都意味着需要有一個文件夾來容納這些東西。

上文中提到的形如spark-local-*的目錄就是用以存儲executor運行時生成的臨時文件。

可以通過兩個簡單的實驗來看spark-local-*目錄下內容的變化。

實驗2:不進行RDD Cache

進入spark-shell之后運行

spark-shell>sc.textFile(“README.md”).flatMap(l=>l.split(“ “)).map(w=>(w,1)).reduceByKey(_ + _).foreach(println)

上述指令會生成兩個不同的Stage, 所以會有Shuffle Output,具體划分原因就不再細述了。

如果使用的是spark 1.2.x,可以看到有在spark-local-*目錄下有index文件生成。

實驗3: 進行RDD Cache

進入spark-shell之后運行

spark-shell>val rdd1 = sc.textFile(“README.md”).flatMap(l=>l.split(“ “)).map(w=>(w,1)).reduceByKey(_ + _)
spark-shell> rdd1.persist(MEMORY_AND_DISK_SER)
spark-shell>rdd1.foreach(println)

上述指令執行后,不僅會有index文件還會有形如rdd*的文件生成,這些rdd打頭的文件就是cache內容。

配置項

可以通過在$SPARK_HOME/conf/spark-env.sh中指定配置內容來更改默認的存儲位置。

SPARK_WORK_DIR 指定work目錄,默認是$SPARK_HOME/work子目錄

SPARK_LOCAL_DIRS 指定executor運行生成的臨時文件目錄,默認是/tmp,由於/tmp目錄有可能是采用了tmpfs,建議在實際部署中將其更改到其它目錄

文件的清理

上述過程中生成的臨時文件在什么時候會被刪除掉呢?

也許第一感覺就是spark application結束運行的時候唄,直覺有時不見得就是對的。

SPARK_LOCAL_DIRS下的產生的文件夾,確實會在應用程序退出的時候自動清理掉,如果觀察仔細的話,還會發現在spark_local_dirs目錄有有諸如*_cache和*_lock的文件,它們沒有被自動清除。這是一個BUG,可以會在spark 1.3中加以更正。有關該BUG的具體描述,參考spark-4323 https://issues.apache.org/jira/browse/SPARK-4323

$SPARK_LOCAL_DIRS下的*_cache文件是為了避免同一台機器中多個executor執行同一application時多次下載第三方依賴的問題而引進的patch,詳見JIRA case spark-2713. 對就的代碼見spark/util/Utils.java中的fetchFile函數。https://issues.apache.org/jira/browse/SPARK-2713

如果已經在使用了,有什么辦法來清除呢?暴力刪除,不管三七二十一,過一段時間將已經存在的cache和lock全部刪除。這不會有什么副作用,大不了executor再去下載一次罷了

find $SPARK_LOCAL_DIRS -max-depth 1 -type f -mtime 1 -exec rm -- {} \;

而SPARK_WORK_DIR目錄下的形如app-timestamp-seqid的文件夾默認不會自動清除。

那么可以設置哪些選項來自動清除已經停止運行的application的文件夾呢?當然有。

在spark-env.sh中加入如下內容

SPARK_WORKER_OPTS=”-Dspark.worker.cleanup.enabled=true”

注意官方文檔中說不管程序是否已經停止,都會刪除文件夾,這是不准確的,只有停止掉的程序文件夾才會被刪除,我已提交相應的PR.

如果Spark應用程序需要長時間運行,生成的許多shuffle output何時再清理呢?可以通過配置spark.cleaner.ttl來設置清理的時間。

實驗4

寫一個簡單的WordCount,然后以Standalone Cluster模式提交運行,察看$SPARK_LOCAL_DIRS下文件內容的變化。

import org.apache.spark._
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.SparkContext._
import java.util.Date
object HelloApp {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    val sc = new SparkContext()
    val fileName = "$SPARK_HOME/README.md"
    val rdd1 = sc.textFile(fileName).flatMap(l => l.split(" ")).map(w => (w, 1))
    rdd1.reduceByKey(_ + _).foreach(println)
    
    var i: Int = 0
    while ( i < 10 ) {
      Thread.sleep(10000)
      i = i + 1
    }
  }
}

提交運行

spark-submit –class HelloApp –master spark://127.0.0.1:7077  --deploy-mode cluster HelloApp.jar	

小結

本文通過幾個簡單易行的實驗來觀測standalone模式下臨時文件的產生和清除,希望有助於理解spark中磁盤資源的申請和釋放過程。

Spark部署時相關的配置項比較多,如果先進行分類,然后再去配置會容易許多,分類有CPUMemoryNetworkSecurityDiskAkka相關。

 

參考資料

  1. https://spark.apache.org/docs/1.2.0/submitting-applications.html
  2. https://spark.apache.org/docs/1.2.0/spark-standalone.html
  3. http://mail-archives.apache.org/mod_mbox/spark-commits/201410.mbox/%3C2c2ce06abc7d48d48f17f8e458a53219@git.apache.org%3E
  4. https://issues.apache.org/jira/browse/SPARK-4323
  5. https://issues.apache.org/jira/browse/SPARK-2713


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM