Spark中,所谓资源单位一般指的是executors,和Yarn中的Containers一样,在Spark On Yarn模式下,通常使用–num-executors来指定Application使用的executors数量,而–executor-memory和–executor-cores分别用来指定每个executor所使用的内存和虚拟CPU核数。
其实从Spark1.2之后,对于On Yarn模式,已经支持动态资源分配(Dynamic Resource Allocation),这样,就可以根据Application的负载(Task情况),动态的增加和减少executors。

配置Spark资源动态分配

进入${SPARK_HOME}/conf/目录,在spark-defaults.conf文件中新增如下配置
如果spark-defaults.conf文件不存在,从spark-defaults.conf.template模板文件拷贝

cp spark-defaults.conf.template spark-defaults.conf
vi spark-defaults.conf

增加或者修改成如下配置

# 启用External shuffle Service服务
spark.shuffle.service.enabled true
# Shuffle Service服务端口,必须和yarn-site中的一致
spark.shuffle.service.port 7337
# 开启动态资源分配
spark.dynamicAllocation.enabled true
# 每个Application最小分配的executor数
spark.dynamicAllocation.minExecutors 1
# 每个Application最大并发分配的executor数
spark.dynamicAllocation.maxExecutors 30
spark.dynamicAllocation.schedulerBacklogTimeout 1s 
spark.dynamicAllocation.sustainedSchedulerBacklogTimeout 5s
动态资源分配策略:

开启动态分配策略后,application会在task因没有足够资源被挂起的时候去动态申请资源,这种情况意味着该application现有的executor无法满足所有task并行运行。spark一轮一轮的申请资源,当有task挂起或等待spark.dynamicAllocation.schedulerBacklogTimeout(默认1s)时间的时候,会开始动态资源分配;之后会每隔spark.dynamicAllocation.sustainedSchedulerBacklogTimeout(默认1s)时间申请一次,直到申请到足够的资源。每次申请的资源量是指数增长的,即1,2,4,8等。
之所以采用指数增长,出于两方面考虑:其一,开始申请的少是考虑到可能application会马上得到满足;其次要成倍增加,是为了防止application需要很多资源,而该方式可以在很少次数的申请之后得到满足。

资源回收策略

当application的executor空闲时间超过spark.dynamicAllocation.executorIdleTimeout(默认60s)后,就会被回收。

将spark目录下的spark--yarn-shuffle.jar(SPARK_HOME/yarn/spark-2.1.0-yarn-shuffle.jar)copy到hadoop集群的所有节点中,我们环境的对应目录为HADOOP_HOME/yarn/lib/

配置yarn

在${HADOOP_HOME}/etc/hadoop/yarn-site.xml文件中添加如下配置:

<property>
   <name>yarn.nodemanager.aux-services</name>
   <value>mapreduce_shuffle,spark_shuffle</value>
</property>
<property>
   <name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
   <value>org.apache.spark.network.yarn.YarnShuffleService</value>
</property>

注意:如果 “yarn.nodemanager.aux-services” 配置项已存在,则在 value 中添加 “spark_shuffle”,且用逗号和其他值分开。
修改yarn-site.xml之后copy至各个节点

增大NodeManager的heap size

通过在$HADOOP_HOME/etc/hadoop /yarn-env.sh中设置YARN_HEAPSIZE(默认为1000)来增加NodeManager的堆大小,以避免shuffle期间的垃圾回收问题。

export YARN_HEAPSIZE=6000

重启集群中所有节点的Spark

重启集群中所有的YARN