一个Executor对应一个JVM进程。 从Spark的角度看,Executor占用的内存分为两部分:1
2
3
4
5
6
7
8
9
10
11
12
13
14
```spark.driver.memory``` 和```spark.executor.memory``` 分别设置Spark的Driver和Executor的```ExecutorMemory```.
```spark.yarn.executor.memoryOverhead```和```spark.yarn.driver.memoryOverhead```分别设置Spark的Driver和Executor的```MemoryOverhead```.
另外,Spark会大量分配堆外内存,堆外内存默认最大可以和```ExecutorMemory```一样,可以通过javaOptions使用```MaxDirectMemorySize```配置最大值。
堆外内存最大可以和```ExecutorMemory```一样,但是堆外内存又受```MemoryOverhead```限制,所以当```MaxDirectMemorySize```,```ExecutorMemory```和```MemoryOverhead```设置不合理时,会出现container内存超限,被Yarn kill的情况。
比如,```ExecutorMemory``` 为8G,```MemoryOverhead```为4G,```MaxDirectMemorySize```没有设置,此时yarn认为一个container最大可以使用12G内存,但是堆外内存最大可以使用8G,导致container最大可以使用超过16G内存(堆内内存+ 堆外内存),比12G大, 最终被Yarn kill掉。
合理的设置规则为: ```ExecutorMemory``` + ```MemoryOverhead``` > ```ExecutorMemory``` + ```MaxDirectMemorySize
所以,Spark应用占用集群内存的总大小为:
(executor个数) * (SPARK_EXECUTOR_MEMORY+ spark.yarn.executor.memoryOverhead)+(SPARK_DRIVER_MEMORY+spark.yarn.driver.memoryOverhead)
参数调优建议:
每个Executor进程的内存设置4G~8G较为合适。
每个Executor的CPU core数量设置为2~4个较为合适。
以下是部分建议的参数设置:
1 | --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" \ |