Spark on Yarn 為什么出現(xiàn)內(nèi)存超界container被kill

一個(gè)Executor對(duì)應(yīng)一個(gè)JVM進(jìn)程。 從Spark的角度看,Executor占用的內(nèi)存分為兩部分:ExecutorMemoryMemoryOverhead。其中,ExecutorMemory為JVM進(jìn)程的Java堆區(qū)域,MemoryOverhead為JVM進(jìn)程中除Java堆以外占用的空間大小,包括方法區(qū)(永久代)、Java虛擬機(jī)棧、本地方法棧、JVM進(jìn)程本身所用的內(nèi)存、堆外內(nèi)存(Direct Memory)等。

spark.driver.memoryspark.executor.memory 分別設(shè)置Spark的Driver和Executor的ExecutorMemory.

spark.yarn.executor.memoryOverheadspark.yarn.driver.memoryOverhead分別設(shè)置Spark的Driver和Executor的MemoryOverhead.

另外,Spark會(huì)大量分配堆外內(nèi)存,堆外內(nèi)存默認(rèn)最大可以和ExecutorMemory一樣,可以通過(guò)javaOptions使用MaxDirectMemorySize配置最大值。

堆外內(nèi)存最大可以和ExecutorMemory一樣,但是堆外內(nèi)存又受MemoryOverhead限制,所以當(dāng)MaxDirectMemorySize,ExecutorMemoryMemoryOverhead設(shè)置不合理時(shí),會(huì)出現(xiàn)container內(nèi)存超限,被Yarn kill的情況。

比如,ExecutorMemory 為8G,MemoryOverhead為4G,MaxDirectMemorySize沒(méi)有設(shè)置,此時(shí)yarn認(rèn)為一個(gè)container最大可以使用12G內(nèi)存,但是堆外內(nèi)存最大可以使用8G,導(dǎo)致container最大可以使用超過(guò)16G內(nèi)存(堆內(nèi)內(nèi)存+ 堆外內(nèi)存),比12G大, 最終被Yarn kill掉。

合理的設(shè)置規(guī)則為: ExecutorMemory + MemoryOverhead > ExecutorMemory + MaxDirectMemorySize

所以,Spark應(yīng)用占用集群內(nèi)存的總大小為:

(executor個(gè)數(shù)) * (SPARK_EXECUTOR_MEMORY+ spark.yarn.executor.memoryOverhead)+(SPARK_DRIVER_MEMORY+spark.yarn.driver.memoryOverhead)

參數(shù)調(diào)優(yōu)建議:

每個(gè)Executor進(jìn)程的內(nèi)存設(shè)置4G~8G較為合適。

每個(gè)Executor的CPU core數(shù)量設(shè)置為2~4個(gè)較為合適。

以下是部分建議的參數(shù)設(shè)置:

--conf "spark.driver.extraJavaOptions=-XX:MaxDirectMemorySize=1024m -Xmn4g -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/tmp/log/run/gc-%t.log" \

--conf "spark.speculation=true" \
--conf "spark.speculation.quantile=0.95" \

--conf "spark.kryoserializer.buffer.max=1024m" \

--conf "spark.sql.hive.metastorePartitionPruning=true" \
--conf "spark.sql.optimizer.metadataOnly=true" \
--conf "spark.sql.parquet.filterPushdown=true" \
--conf "spark.sql.hive.caseSensitiveInferenceMode=NEVER_INFER" \
--conf "spark.sql.hive.convertMetastoreParquet=false" \

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容