场景描述

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 的内存。

这就解释了为何实际分配的资源比我们申请的资源大。