spark学习笔记3 spark应用程序之间的调度

1、调度配置

Standalone集群模式:默认情况下,提交给Standalone集群的应用程序以FIFO(first in, first out)顺序执行,同时,每个应用程序都会尝试使用所有可用的节点。你可以通过设置属性spark.cores.max来限制应用程序能使用的节点数目,或者,对于那些未设置该属性的应用程序,还可以通过设置属性spark.deploy.defaultCores来改变默认的资源分配方式(即每个应用使用所有可用节点)。最后,除了控制CPU核数外,每个应用程序可以通过属性spark.executor.memory来控制其内存用量。

Mesos集群模式:要在Mesos集群上使用静态资源分区,将属性spark.mesos.coarse配置为true即可,还可以根据需要设置属性spark.cores.max来限制每个应用程序所占用的资源,如同在Standalone集群模式下所做的配置一样。你还应当设置属性spark.executor.memor来控制executor的内存占用量。

YARN集群模式:用于Spark YARN客户端的命令行选项--num-executors控制着应用程序要在集群上分配多少个executor来执行作业,而选项--executor-memory和--executor-cores则分别控制着每个executor所用的内存量和CPU核数。

2、应用程序内部的job调度

在spark程序的内部,用户通过不同线程提交的job可以并行运行,这里说的job就是spark action算子触发的整个RDD DAG为一个job。

(1)FIFO

默认条件下,spark的调度器以fifo调度job的执行。优先分配资源给第一个job。

不看了,

(2)fair

从Spark 0.8版开始,通过配置我们就可以让各个作业公平地共享资源。在公平资源共享模式下,spark以轮转(round robin)方式在各个作业(job)之间分配任务(task),以便所有作业都能大致平等地共享集群资源。这就意味着,在长期作业正在运行时提交的短期作业可以立即获得资源并得到良好的响应时间,而无需等待长期作业执行完毕。该模式对于多用户环境是最佳的。要启用公平作业调度,在创建一个SparkContext之前,需要简单的配置spark.scheduler.mode为FAIR。

fair调度池:

fair scheduler调度器还支持把作业分组放入调度池(pool)里,并为每个调度池设置不同的调度选项(如权重weight)。这个功能是很有用的,例如,对于那些更重要的作业设置优先级,或者把每个用户的作业分别合并为一组,无论他们各自有多少个并发作业,都让其平等地共享资源,而不是让每个作业平等地共享资源。这种方法是基于Hadoop Fair Scheduler来实现的。

无需任何干预,新提交的作业会进入默认调度池,但是作业所属的调度池也是可以设置的,即在提交作业的那个线程内,向SparkContext中添加本地属性(local property)spark.scheduler.pool就能实现。方法如下:

sc.setLocalProperty("spark.scheduler.pool", "pool1")
设置了该本地属性之后,此线程中提交的所有作业(在此线程中调用RDD.save,count,collect等)都将使用这个调度池名称。这个设置是每个线程中都有一个,便于让一个线程以同一用户的名义运行多个作业。如果你想清空与该线程关联的调度池,可以简单地调用:

sc.setLocalProperty("spark.scheduler.pool", null)

 默认情况下,每个调度池都会平等地共享集群资源(在默认调度池内的每个作业也都是平等地共享资源) ,但在每个调度池内,各个作业以FIFO顺序运行。例如,如果你为每个用户各创建一个调度池,也就意味着每个用户都将平等地共享集群资源,且每个用户的查询作业将按顺序运行,而不是后续的查询作业抢占该用户之前的查询作业已经获得的资源。

对于特定的调度池,其属性也可以通过配置文件来修改。每个调度池都支持以下三个属性:

schedulingMode:该属性可以设为FIFO或FAIR,用来控制调度池内的各个作业是按照排队顺序执行(默认行为),还是平等地共享该调度池的资源。
weight:该属性控制一个调度池与其他调度池共享集群资源的方式。默认情况下,所有调度池的权重均为1。举例来说,如果你将某个调度池的权重设为2,那么,它获得的资源将是其他调度池的两倍。设置一个较高的权重(比如1000)还可能实现调度池之间的优先级——基本上,权重为1000的调度池无论何时有活动的作业,它都总是优先执行其任务(task)。
minShare:除了设定调度池的总体权重外,每个调度池都可以设置共享资源的最小数量(如CPU核数)。在根据权重重新分发额外的资源之前,fair scheduler调度器总是尝试去满足所有活跃调度池所需的共享资源的最小数量。因此,minShare属性就成了确保调度池在无需设置高优先级的情况下就能快速获得定量资源(如10个CPU核)的又一种方法。默认情况下,每个调度池的minShare属性值为0.
调度池的属性可以通过创建一个XML文件(类似于conf/fairscheduler.xml.template)并在你的SparkContext中设定属性spark.scheduler.allocation.file来配置。

<?xml version="1.0"?>
<allocations>
  <pool name="production">
    <schedulingMode>FAIR</schedulingMode>
    <weight>1</weight>
    <minShare>2</minShare>
  </pool>
  <pool name="test">
    <schedulingMode>FIFO</schedulingMode>
    <weight>2</weight>
    <minShare>3</minShare>
  </pool>
</allocations>
3、Stage TaskSetManager调度方式

(1)stage的生成

stage的调度是由DAGScheduler完成的。由RDD的DAG切分出Stage的DAG,stage的DAG通过最后执行的stage为根进行广度优先遍历,遍历到最开始执行的Stage执行,如果提交的Stage仍有未完成的父母Stage,则Stage需要等待其父Stage执行完才能执行。 同时DAGScheduler中还维持了几个重要的Key-Value集合结构,用来记录Stage的状态,这样能够避免过早执行和重复提交Stage。 waitingStages中记录仍有未执行的父母Stage,防止过早执行。 runningStages中保存正在执行的Stage,防止重复执行。failedStages中保存执行失败的Stage,需要重新执行,这里的设计是出于容错的考虑。其调度是在DAGScheduler中完成的。

(2)tasksetmanager的调度

每个Stage对应一个TaskSetManager,通过Stage回溯提交到调度池,在调度池中又根据JobID排序,先提交的Job的TaskSetManager优先调度,同一个Job内的TaskSetManager ID小的先调度。

4、Task调度(看不太懂,以后用的时候慢慢看,下面简介下)

(1)分配任务执行节点
   1)如果是调用过cache()方法的RDD,数据已经缓存在内存,则读取内存缓存中分区的数据。

   2)如果直接能获取到执行地点,则返回执行地点作为任务的执行地点,通常DAG中最源头的RDD或者每个Stage中最开始的RDD会有执行地点的信息。 

  3)如果不是上面两种情况,将遍历RDD获取第一个窄依赖的父亲RDD对应分区的执行地点。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章