一個(gè)Executor對(duì)應(yīng)一個(gè)JVM進(jìn)程。 從Spark的角度看,Executor占用的內(nèi)存分為兩部分:ExecutorMemory和MemoryOverhead。其中,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.memory 和spark.executor.memory 分別設(shè)置Spark的Driver和Executor的ExecutorMemory.
spark.yarn.executor.memoryOverhead和spark.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,ExecutorMemory和MemoryOverhead設(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" \