场景描述
spark on yarn 提交多个任务后,只有一个在 RUNNING 状态执行,其余任务都是 ACCEEPTED 状态,而且集群有好多资源没有被使用。让 yarn 同时执行多个任务,可以提高集群资源的利用效率,也能提高任务的执行效率。
实现方法
修改 yarn 集群的配置。${HADOOP_HOME}/etc/hadoop/capacity-scheduler.xml
<property>
<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
<value>0.1</value>
<description>
Maximum percent of resources in the cluster which can be used to run
application masters i.e. controls number of concurrent running
applications.
</description>
</property>
description 写的很清楚:所有正在运行的 application 使用的资源占集群总资源的最大百分比。换句话说,这个配置控制着 yarn 平台并行执行任务的数量。
举个栗子:
集群总资源 100G
占比(默认)0.1 -->> 100G * 0.1 = 10G (正在运行的全部任务所用资源不得超过 10 G)
每个 application 占 2 G ---> 同时 RUNNING 5 个 application。
每个 application 占 3 G ---> 同时 RUNNING 3 个 application。
每个 application 占 4 G ---> 同时 RUNNING 2 个 application。
每个 application 占 5 G ---> 同时 RUNNING 2 个 application。
每个 application 占 6 G ---> 同时 RUNNING 1 个 application。
所以当百分比越高的时候,可以同时并行的 application 数量就越多。
修改上述参数后,重新启动 yarn,配置就生效了。
yarn 资源配置
经常会看到一个现象,RUNNING 状态的 application 使用的内存资源大于我们提交任务时申请的资源数。出现这种现象有两个原因:
executor 和 driver 内存资源分配公式
实际 executor 分配的内存 = 申请的内存 + 额外配置的内存。
额外配置的内存 = MIN (申请的内存 * spark.yarn.am.memoryOverhead,384M)
spark.yarn.am.memoryOverhead 可以自行配置,默认 0.1。
举个例子:
提交任务时申请 1G exectuor。
额外配置的内存 = 1G * 0.1 = 102M
因为 102M 小于 384M,所以额外配置的内存 = 384M。
则 实际 executor 分配的内存 = 1G + 384M = 1408M
最小资源分配数
yarn 平台为任务分配资源的时候,有最小资源分配数和最大资源分配数的限制,且这两个限制都可以通过配置参数修改。
在 ${HADOOP_HOME}/etc/hadoop/yarn-site.xml
中修改。
yarn.scheduler.minimum-allocation-mb
单个 container 可以申请的最小的物理内大小。默认:1024M
yarn.scheduler.maximum-allocation-mb
单个 container 可以申请的最大的物理内大小。默认:8192M
在处理为 executor 分配 1408M 内存的请求时,实际会为其分配 2G 的内存。
这就解释了为何实际分配的资源比我们申请的资源大。