spark的作业调度问题

1. 文档来源
http://spark.apache.org/docs/1.6.1/job-scheduling.html


2. 调度策略
spark有多种策略在计算之间进行资源规划。


一个spark application,是一个spark应用。一个应用,有且仅有,对应且仅对应一个sparkContext。每一个应用,运行一组独立的executor processes。一个应用,可以以多线程的方式提交多个作业job。spark可以运行在多种集群管理器上,如mesos,yarn,以及standalone,每种集群管理器都会提供跨应用的资源调度策略。




3. 静态资源调度
最简单的资源分配方式,是静态切分。在这种情况下,集群管理器给每个spark应用配置了它能使用的最大资源,且让它在整个生命周期里一直使用这些资源。standalone,yarn和coase-grained mesos mode,都有这种分配方式。我们初期只使用standalone模式。在这种方式下,一个应用如果被提交到spark集群运行,它会按照fifo方式运行,也就是first-in-first-out,它在运行时,会使用集群的所有节点,如果想对应用加以资源约束,可以设置spark.cores.max属性以限制使用的最多cpu数量,或者设置spark.deloy.defaultCores更改默认cpu数量,还可以通过spark.executor.memenory设置应用所使用的内存。


注意:至今没有实现集群管理器实现 不同应用之间的 内存共享。spark推荐的方式是,运行一个单服务应用,在这个应用里放一些共用的RDD,其他应用统一到这里进行数据query。未来,Spark将使用Tachyon提供共享RDD的服务。


Tachyon是spark生态系统的分布式内存文件系统,这是介绍http://www.csdn.net/article/2015-06-25/2825056。Tachyon跟spark同源,也是出自amplab,作者是li haoyun,作者的Tachyon论文在这里https://people.eecs.berkeley.edu/~haoyuan/papers/2013_ladis_tachyon.pdf,作者的主页在这里https://people.eecs.berkeley.edu/~haoyuan/。 Tachyon现在改名叫Alluxio,官网是http://www.alluxio.org/。




4. 动态资源调度
spark提供动态调度资源功能。如果一个应用不再使用资源,就可以将资源还给集群,如果需要再次使用,能从集群获取。如果多个应用在集群上运行,动态调度资源特性是非常有用的。


在默认情况下,三种集群管理器均不使用动态资源调度模式。所以要使用动态资源调度需要提前配置。


如果要使用动态资源调度功能,首先,在应用里,需要设置spark.dynamicAllocation.enable为true。其次,在应用里,设置spark.shuffle.service.enabled为true。再次,将集群的每一个worker节点都设置external shuffle service,如果资源管理器是standalone,就简单了,只要在worker节点设置spark.shuffle.service.enabled为true就行了。




5. 资源分配策略
各种应用的实际运行情况是难以预计测。因此,在资源的获取和返目前还只能使用一些启发式规则。


请求策略:
一个应用applicaiton,有一个或者多个job作业,一个作业job有一个或者多个task。如果一个应用application,自己的某些task任务被做了pending操作以等待被调度执行,那么,它就需要动态申请更多的资源。


如果一个task任务等待被执行的时间超过spark.dynamicAllocation.schedulerBacklogTimeout的秒数,就会引发一个申请exectutor资源的事件,如果被pengding的任务的序列始是非空,那么每一次超时,都是引发资源申请。申请资源的数量是指数增长的,第一次申请一个,第二次申请2个,第三次申请4, 第四次申请8个,以此类推。


返回策略:
这个策略很简单,如果一个应用的某个executor的最后一次闲置idle时间超过spark.dynamicAllocation.executorIdleTimeout的秒数,那么,这个executor就会被返回给集群。


6. 如何安全返还Executor
一个spark的Executor,只有在出错或者它对应的应用执行完毕的时候,才会被返还给集群。在这两种状态下,这个executor的所有状态都没用了,不需要保存,将被直接丢弃。但,在动态资源分配策略下,就不能丢弃状态信息了,因为这个executor对应的应用可能还在运行,只是不需要这个executor而已,如果这时候将状态信息丢弃了,应用将来找不到这些状态信息,就不得不重新运行相关任务计算出这些信息。因此,spark需要一种机制,能保存一个将被返还到集群的executor的状态信息,以备对应的应用在需要的时候使用这些信息。


这些状态信息,最重要的就是shuffles信息。对shuffle来说,executor现将自己的map输出写入到磁盘,然后,自己作为一个server,向其他executor提供这些map输出文件的数据。而动态资源调度将executor返还给集群后,这个shuffle数据服务就没有了。因此,如果要使用动态资源策略,解决这个问题的办法就是,将保持shuffle文件作为一个外部服务,始终运行在spark集群的每个节点上,独立于应用和executor,(于是,从本质上说,这种方式实际上就类似前面提到的Tachyon,分布式内存文件系统,可见这是一个强需求)。


还有一些状态信息,是executor缓存在磁盘和内存里的数据,这块没解决,丢了就丢了。在未来的版本会解决这个问题。估计也是和Tachyon一样。




7. 应用间的调度问题
一个应用applicaiton,有多个平行的job作业。一个作业job,也就是spark action如save和collect和那些计算action所执行的任何task任务。


默认情况下,spark的调度器以FIFO的方式执行作业job。每个作业切分成若干个stage。第一个job在运行的时候,将获得最高优先权,使用所有能得到的资源,然后它的stage进入执行状态,执行完了之后,第二个job获得最高优先权,其他以此类推。如果第一个job不使用全部集群节点,那么后面的job可以立刻进入运行状态。


从spark0.8之后,可以在job作业之间配置fair sharing模式。在fair sharing下,spark在多任务job上使用 round robin,这样所有的job都能粗略地得到几乎相等的集群资源。这就意味着,在长作业job运行的时候,短作业job也能被提交且能立刻得到资源运行,而不是等待长作业运行结束才能运行。


如果想使用fair sharing调度,只要设置spark.scheduler.mode属性成FAIR即可,比如说,对sparkContext进行如下配置:
val conf = new SparkConf().setMaster(...).setAppName(...)
conf.set("spark.scheduler.mode", "FAIR")
val sc = new SparkContext(conf)






8. Fair Scheduler Pools 公平调度器池
公平调度器,将多个任务进行分组,放入池里。然后对每个池,设置不同的调度参数,比如权重。这样,可以创建一个 高优先级的池管理重要作业。或者,可以将每个用户提交的作业放到这个用户专用池里,然后给每个用户相同的集群资源,这样不管每个用户运行多少任务,能给每个用户同样的集群份额使用权,避免一个用户占用所有资源而其他用户不能使用的问题。


在默认情况下,新作业会被提交到默认的pool。如果要将作业提交到某个pool,需要进行声明,比如:
// Assuming sc is your SparkContext variable
sc.setLocalProperty("spark.scheduler.pool", "pool1")
sc是线程安全的,如果在一个线程里提交多个作业,那么,按照上述方式设置后,这个线程里提交的作业都会放入到pool1里。


每个池,有相同的使用集群的权利。而在每个池的内部,作业job是按照FIFO的次序运行的。


在配置文件里,配置pools属性:
schedulingMode,设置为FIFO或者FAIR,它决定池内的作业job是以顺序执行,还是共享池的资源。
weight, 这个权重,决定池和池之间如何分配整个集群的资源。默认情况下,所有池的权重都是1,如果你给某个池的权重是2,那么它就获得常规池两倍的资源。最高可以设置到1000,这就意味着这个池只要有任务就会立刻执行。
minShare,除了权重,还可以对每个池设置最小数量的集群使用份额,也就是cpu数量。这个优先级是最高的,fair调度器在重新分配资源之前,首先要给每个pool赋予minShare的资源,然后再对其他资源按照前述策略进行分配。


在代码里,可以对池的配置进行设置,指定池策略的xml文件即可,形如:
conf.set("spark.scheduler.allocation.file", "/path/to/file")
池配置xml文件类似conf/fairscheduler.xml.template文件。比如,这是一个池配置文件。
<?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>



































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值