簡體   English   中英

作業運行成功時,驅動程序內存,執行程序內存,驅動程序內存開銷和執行程序內存開銷的Apache Spark效果

[英]Apache Spark Effects of Driver Memory, Executor Memory, Driver Memory Overhead and Executor Memory Overhead on success of job runs

我正在對YARN上的Spark作業進行一些內存調整,我注意到不同的設置會產生不同的結果並影響Spark作業運行的結果。 但是,我很困惑,並不完全理解為什么會發生這種情況,如果有人可以提供一些指導和解釋,我會很感激。

我將提供一些背景信息並發布我的問題,並描述我之后經歷過的案例。

我的環境設置如下:

  • 內存20G,每個節點20個VCores(總共3個節點)
  • Hadoop 2.6.0
  • Spark 1.4.0

我的代碼遞歸地過濾RDD以使其變小(將示例作為算法的一部分移除),然后執行mapToPair並收集以收集結果並將其保存在列表中。

問題

  1. 為什么拋出不同的錯誤並且第一個和第二個案例之間的作業運行時間更長(第二種情況)只有執行程序內存增加了? 這兩個錯誤是否以某種方式相關聯?

  2. 第三和第四種情況都成功了,我明白這是因為我提供了更多的內存來解決內存問題。 但是,在第三種情況下,

spark.driver.memory + spark.yarn.driver.memoryOverhead = YARN將創建JVM的內存

= 11g +(driverMemory * 0.07,最小值為384m)= 11g + 1.154g = 12.154g

所以,根據公式,我可以看到我的工作需要大約12.154g的MEMORY_TOTAL才能成功運行,這解釋了為什么我需要超過10g的驅動程序內存設置。

但對於第四種情況,

spark.driver.memory + spark.yarn.driver.memoryOverhead = YARN將創建JVM的內存

= 2 +(driverMemory * 0.07,最小值為384m)= 2g + 0.524g = 2.524g

似乎只需將內存開銷增加少量的1024(1g),就可以成功運行作業,驅動程序內存僅為2g,而MEMORY_TOTAL僅為2.524g 而沒有開銷配置,驅動程序內存小於11g會失敗,但從公式中沒有意義,這就是為什么我感到困惑。

為什么增加內存開銷(對於驅動程序和執行程序)允許我的作業以較低的MEMORY_TOTAL(12.154g vs 2.524g)成功完成? 在這里有一些其他內部事物在我失蹤嗎?

第一個案例

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 7g --executor-memory 1g --num-executors 3 --executor-cores 1 --jars <jar file>

如果我用任何小於11g的驅動程序內存運行我的程序,我將得到下面的錯誤,即停止的SparkContext或類似的錯誤,這是在停止的SparkContext上調用的方法。 從我收集的內容來看,這與記憶力不足有關。

DriverMemory-7g_ExecutorMemory-1G

第二個案例

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 7g --executor-memory 3g --num-executors 3 --executor-cores 1 --jars <jar file>

如果我運行具有相同驅動程序內存但執行程序內存較高的程序,則作業比第一種情況運行時間更長(約3-4分鍾),然后它將遇到與先前不同的錯誤,這是一個請求/使用更多內存的容器允許並因此而被殺害。 雖然我發現它很奇怪,因為執行程序內存增加了,並且在第一種情況下發生了此錯誤而不是錯誤。

DriverMemory-7g_ExecutorMemory-3G

第三個案例

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 11g --executor-memory 1g --num-executors 3 --executor-cores 1 --jars <jar file>

驅動程序內存大於10g的任何設置都將導致作業能夠成功運行。

第四個案例

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 2g --executor-memory 1g --conf spark.yarn.executor.memoryOverhead=1024 --conf spark.yarn.driver.memoryOverhead=1024 --num-executors 3 --executor-cores 1 --jars <jar file>

使用此設置將成功運行作業(驅動程序內存2g和執行程序內存1g,但會增加驅動程序內存開銷(1g)和執行程序內存開銷(1g)。

任何幫助將不勝感激,並將真正幫助我理解Spark。 提前致謝。

所有案例都使用

--executor-cores 1

這是最好的做法,超過1.並且不要超過5.從我們的經驗和Spark開發人員的推薦。

例如http://blog.cloudera.com/blog/2015/03/how-to-tune-your-apache-spark-jobs-part-2/

A rough guess is that at most five tasks per executor 
can achieve full write throughput, so it’s good to keep 
the number of cores per executor below that number

我現在找不到參考建議每個執行者超過1個核心的地方。 但是這個想法是在同一個執行器中運行多個任務使您能夠共享一些公共內存區域,從而實際上節省了內存。

從--executor-cores 2開始,雙--executor-memory(因為--executor-cores還告訴一個執行程序將運行多少個任務),並看看它為你做了什么。 您的環境在可用內存方面是緊湊的,因此轉到3或4將為您提供更好的內存利用率。

我們使用Spark 1.5並且很久以前停止使用--executor-cores 1,因為它給出了GC問題; 它看起來也像是一個Spark bug,因為只是提供更多的內存並沒有幫助,只需要切換到每個容器有更多的任務。 我想同一個執行程序中的任務可能會在不同的時間達到內存消耗的高峰,所以你不要浪費/不必為了使它工作而過度配置內存。

另一個好處是Spark的共享變量(累加器和廣播變量)每個執行器只有一個副本,而不是每個任務 - 所以每個執行器切換到多個任務就是直接節省內存。 即使您沒有顯式使用Spark共享變量,Spark也很可能在內部創建它們。 例如,如果您通過Spark SQL連接兩個表,Spark的CBO可能決定廣播較小的表(或較小的數據幀)以使連接運行更快。

http://spark.apache.org/docs/latest/programming-guide.html#shared-variables

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM