在运行Spark作业时,YARN不会基于公平份额抢占资源

Mom*_*lov 20 hadoop job-scheduling hadoop-yarn apache-spark

我在YARN Fair Scheduled队列上重新平衡Apache Spark作业资源时遇到问题.

对于测试,我已经配置了Hadoop 2.6(也尝试过2.7)以在MacOS上使用本地HDFS以伪分布式模式运行.对于作业提交使用Spark的网站上的 "Pre-build Spark 1.4 for Hadoop 2.6 and later"(也试过1.5).

在Hadoop MapReduce作业上使用基本配置进行测试时,Fair Scheduler按预期工作:当群集资源超过某个最大值时,将计算公平份额,并根据这些计算抢占和平衡不同队列中作业的资源.

使用Spark作业运行相同的测试,在这种情况下,YARN正在为每个作业正确计算公平份额,但Spark容器的资源不会重新平衡.

这是我的conf文件:

$ HADOOP_HOME的/ etc/Hadoop的/纱线的site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
   <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
   </property>
   <property>
      <name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
      <value>org.apache.spark.network.yarn.YarnShuffleService</value>
   </property>
   <property>
      <name>yarn.resourcemanager.scheduler.class</name>
      <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
   </property>
   <property>
      <name>yarn.scheduler.fair.preemption</name>
      <value>true</value>
   </property>
</configuration>
Run Code Online (Sandbox Code Playgroud)

$ HADOOP_HOME的/ etc/Hadoop的/公平scheduler.xml

<?xml version="1.0" encoding="UTF-8"?>
<allocations>
   <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
   <queue name="prod">
      <weight>40</weight>
      <schedulingPolicy>fifo</schedulingPolicy>
   </queue>
   <queue name="dev">
      <weight>60</weight>
      <queue name="eng" />
      <queue name="science" />
   </queue>
   <queuePlacementPolicy>
      <rule name="specified" create="false" />
      <rule name="primaryGroup" create="false" />
      <rule name="default" queue="dev.eng" />
   </queuePlacementPolicy>
</allocations>
Run Code Online (Sandbox Code Playgroud)

$ HADOOP_HOME的/ etc/Hadoop的/核心的site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
   <property>
      <name>fs.defaultFS</name>
      <value>hdfs://localhost:9000</value>
   </property>
</configuration>
Run Code Online (Sandbox Code Playgroud)

$ HADOOP_HOME的/ etc/Hadoop的/核心的site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
   <property>
      <name>dfs.replication</name>
      <value>1</value>
   </property>
</configuration>
Run Code Online (Sandbox Code Playgroud)

测试案例是:

在权重为40的"prod"队列上运行作业(必须分配所有资源的40%),正如预期的那样,作业将获得所有需要的免费资源(62.5%的集群资源).

./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn-cluster \
--driver-memory 512M \
--executor-memory 768M \
--executor-cores 1 \
--num-executors 2 \
--queue prod \
lib/spark-examples*.jar 100000
Run Code Online (Sandbox Code Playgroud)

之后在权限为60的"dev.eng"队列中运行相同的作业,这意味着作业必须分配所有资源的60%并将第一个作业的资源减少到~40%.

./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn-cluster \
--driver-memory 512M \
--executor-memory 768M \
--executor-cores 1 \
--num-executors 2 \
--queue dev.eng \
lib/spark-examples*.jar 100000
Run Code Online (Sandbox Code Playgroud)

不幸的是,集群资源没有变化 - 第一份工作为62.5%,第二份工作为37.5%.

Roj*_*Sam 0

公平调度程序不会为第一个作业杀死容器,它只会等到一些资源被释放并保留它们以供第二个作业使用。如果第一个作业没有释放资源,调度程序就无法将这些资源分配给第二个作业。

在MapReduce作业中,每个map或reduce任务都需要实例化一个新容器,如果超出了其报价(基于队列容量),调度程序可以阻止作业实例化新容器。

在 Spark 中情况有所不同,执行器在作业开始时启动,并向它们发送不同的任务(阶段)。那么资源就没有被释放,也不能被重新分配。

动态分配可能会有所帮助:http://spark.apache.org/docs/1.6.1/configuration.html#dynamic-allocation