YARN Container 与 Spark Executor 的数量关系
在 Spark on YARN 部署模式下,YARN Container 和 Spark Executor 的数量确实存在对应关系,但并不是简单的一对一关系。
主要关系
每个 Spark Executor 运行在一个 YARN Container 中
- 一个 YARN Container 通常对应一个 Spark Executor 进程
- 但一个 Container 可能包含多个 Executor(通过特殊配置)
数量控制参数:
YARN 侧:
yarn.nodemanager.resource.memory-mb
: 每个节点可用的总内存yarn.nodemanager.resource.cpu-vcores
: 每个节点可用的总vcoresyarn.scheduler.minimum-allocation-mb
: 单个Container最小内存
Spark 侧:
spark.executor.instances
: 要启动的Executor数量spark.executor.memory
: 每个Executor的内存spark.executor.cores
: 每个Executor的CPU核数spark.dynamicAllocation.enabled
: 是否启用动态分配
数量计算公式
1. 静态分配模式
Executor数量 = min(
spark.executor.instances,
(总YARN资源) / (每个Executor请求的资源)
)
2. 动态分配模式
初始Executor数 = spark.dynamicAllocation.initialExecutors
最大Executor数 = spark.dynamicAllocation.maxExecutors
最小Executor数 = spark.dynamicAllocation.minExecutors
实际示例
假设一个YARN集群有:
- 10个节点
- 每个节点100GB内存和32个vcores
- YARN配置保留20%资源给系统
Spark应用配置:
spark-submit \
--master yarn \
--num-executors 50 \
--executor-memory 4G \
--executor-cores 2 \
...
计算:
- 每个Executor需要:4GB内存 + 2 vcores
- 总可用资源:10节点 × (80GB内存 + 25 vcores) ≈ 800GB + 250 vcores
- 理论最大Executor数:min(800/4, 250/2) = min(200, 125) = 125
- 但应用只请求了50个,所以最终启动50个Executor
重要注意事项
AM Container:
- Application Master也占用一个Container
- 这个Container不计入Executor数量
Overhead:
- YARN有约7%的内存开销
- Spark也有约10%的内存开销(由
spark.executor.memoryOverhead
控制)
动态分配:
- 启用后,Executor数量会根据负载动态调整
- 初始数量由
spark.dynamicAllocation.initialExecutors
决定
资源碎片:
- 如果资源配置不当,可能导致资源浪费
- 例如剩余内存不足以启动新的Executor但总量还很充足