spark on yarn 资源计算

1、spark job 提交模式
spark on yarn 分两种情况,一种是yarn-client 提交,一种是yarn-cluster提交方式,两种方式的区别是:
yarn-cluster模式下,driver运行在AM(Application Master)中,它负责向YARN申请资源,并监督作业的运行状况。当用户提交了作业之后,就可以关掉Client,作业会继续在YARN上运行;
yarn-client模式下,Application Master仅仅向YARN请求executor,client会和请求的container通信来调度他们工作;
其中yarn集群包含RM,NM,AM的概念如下:
ResourceManager:是集群所有应用程序的资源管理器,能够管理集群的计算资源并为每个Application分配,它是一个纯粹的调度器。 
NodeManager:是每一台slave机器的代理,执行应用程序,并监控应用程序的资源使用情况。 
Application Master:每一个应用程序都会有一个Application Master,它的主要职责是向RM申请资源、在每个NodeManager上启动executors、监控和跟踪应用程序的进程等。
spark中driver的作用:
- 运行应用程序的main函数 
- 创建spark的上下文 
- 划分RDD并生成有向无环图(DAGScheduler) 
- 与spark中的其他组进行协调,协调资源等等(SchedulerBackend) 
- 生成并发送task到executor(taskScheduler)
driver中包括一些在executor上运行进程都有的运行环境sparkenv和一些只有driver才拥有的组件比如SparkUI、SchedulerBackEnd、TaskSchduler、DagScheduler等等,整个大框就是一个sparkcontext;
Driver program:The process running the main() function of the application and creating the sparkContext.
 在yarn-cluster模式下,client将用户程序提交到到spark集群中就与spark集群断开联系了,此时client将不会发挥其他任何作用,仅仅负责提交。在此模式下。AM和driver是同一个东西,但官网上给的是driver运行在AM里,可以理解为AM包括了driver的功能就像Driver运行在AM里一样,此时的AM既能够向AM申请资源并进行分配,又能完成driver划分RDD提交task等工作。
yarn-client模式下,Driver运行在客户端上,先有driver再用AM,此时driver负责RDD生成、task生成和分发,向AM申请资源等 ,AM负责向RM申请资源,其他的都由driver来完成。
 
2、两种模式下,资源计算公式
两种提交模式的计算公式:
1)、yarn-client资源计算:
    total vores = executor-cores * num-executors + spark.yarn.am.cores
    total memory = (executor-memory + spark.yarn.executor.memoryOverhead) * num-executors + (spark.yarn.am.memory + spark.yarn.am.memoryOverhead)
2)、yarn-cluster资源计算:
    total vores = executor-cores * num-executors + spark.driver.cores
    total memory = (executor-memory + spark.yarn.executor.memoryOverhead) * num-executors + (spark.driver.memory + spark.driver.memoryOverhead)
 由上公式可知,spark的资源占用计算,关键是spark的memoryOverhead的计算。
 
3、从spark源码角度分析内存占用
以spark 2.4为例,在YarnAllocator.scala 中对memoryOverhead.scala 中做了计算定义:

即如果sparkConf中指定了EXECUTOR_MEMORY_OVERHEAD,则采用指定的,否则,采用math.max((MEMORY_OVERHEAD_FACTOR * executorMemory).toInt, MEMORY_OVERHEAD_MIN)).toInt 值;

而MEMORY_OVERHEAD_FACTOR 的值在 YarnSparkHadoopUtil.scala中做了定义,默认是0.1,MEMORY_OVERHEAD_MIN默认是384M。

 

 
在spark 2.4中,am的memoryOverHead的定义也是类似:

即每个container的内存大小为:memory + memoryOverhead

 而在YARN中,Container申请的内存大小必须为yarn.scheduler.minimum-allocation-mb的整数倍,yarn.scheduler.minimum-allocation-mb 参数在etc/hadoop下的yarn-site.xml中配置

 
如图,如果配置为128,即container最小分配内存为128M,
则单个excutor(即container)占用的内存为,伪代码为(假设yarn.scheduler.minimum-allocation-mb 为128M,MEMORY_OVERHEAD_FACTOR  为0.1,MEMORY_OVERHEAD_MIN 为384M):
if (excutor_memory + excutor_memory*0.1)%384 == 0:
contain_memory = excutor_memory + excutor_memory*0.1
else:
contain_memory = ((excutor_memory + excutor_memory*0.1) / 128 +1)*128
 假设excutor-memory分配的内存为4G,contain_memory 资源占用为:
4*1024 + 4*1024*0.1 = 4523.2
很显然不满足最小分配内存的整数倍:
( 4523.2/128 +1)*128 = 4608 M = 4.5G
即单个excutor占用的内存为4.5G,然后再乘以excutor_num,加上driver_memory的内存占用(和单个excutor的内存计算方式一致),即为这个JOB的总资源占用。
经过本地测试,这样算下来的内存和yarn 8088界面中的内存占用是一致的。

http://{resource_manager_ip}:8088/ws/v1/cluster/metrics

yarn的总内存占用,可以通过上述url访问获取,其中resource_manager_ip为resource_manager的IP,不同集群环境不一致:

 
posted @ 2019-03-26 17:38  Clerver  阅读(1420)  评论(0编辑  收藏  举报