Spark 2.4.8 Job调度

概览

Spark 有多种工具为资源调度在复杂计算. 首先,回顾下,在集群模式概念中,每个 Spark application(SparkContext实例)运行一个独立一组executor 进程.群集管理 Spark运行的集群管理器提供工具为了调度跨应用. 其次,每个Spark application, 多个"jobs"(spark actions)可以并行运行,如果他们提交到不同 线程. 这里常见的,如果你的应用通过网络请求提供服务.Spark包含公平调度来调度资源在每个SparkContext.

跨应用程序调度

当运行在群集上,每个 Spark application获得独立的一组executor JVMs,它只运行任务和为application存储数据.如果多个用户需要共享你的集群,有不同的选项来管理分配,这取决于集群管理器.

最简单的选项,可以用在所有集群管理器,是静态分区资源.用这种方法,每个应用给一个最大的资源,它可以使用并在整个运行阶段一直占用.这个方法被用在 Spark’s standalone 和YARN 模式,也在 coarse-grained Mesos模式里.资源配置可以通过下边,是根据集群类型:

  • Standalone mode: 默认,应用提交到Standalone mode集群会运行先进先出顺序,并且 每个应用会试着使用所有可用节点. 你可以限制应用中node数量使用spark.cores.max配置合适值,或者改变应用默认值没有 设置这个 配置通过spark.deploy.defaultCores.最后,另外控制核数量,每个application的spark.executor.memory设置控制使用的内存.
  • Mesos: 使用静态分区在Mesos中,设置spark.mesos.coarse配置属性为true,并且可选项spark.mesos.coarse来限制每个 application共享资源在standalone mode.你也应该设置spark.executor.memory来控制executor内存.
  • Yarn: 对于Spark YARN 客户端–num-executors选项控制多少个executors 分配在集群上(spark.executor.instances作为配置属性),虽然–executor-memory(spark.executor.memory选项)和–executor-cores(spark.executor.cores配置属性)控制每个executor资源.更多信息查看Yarn Spark 属性.
    第二个在Mesos 上可用选项是动态分配CPU cores.在这个模式中,每个 Spark application仍然有固定和独立内存分配(设置通过spark.executor.memory),但是当application 没有运行任务在机器时,其它application 可能运行任务在这些核上.这种有用的当你期望大量没有运行的应用时,像来到不同用户的shell session.然而,他可以带来一个难以预测的延时,因为它可能等因为一个application获得cores在运行.使用这种模式,简单使用 mesos:// URL和设置 spark.mesos.coarse为false.

注意当前没有一个模式提供跨application内存共享.如果你想要用这样方式共享数据 ,我们推荐运行一个单独server可以提供多个请求通过查询相同的RDD.

动态资源分配

Spark提供一个机制动态调整你的程序占用的资源基于工具负载.这意味着你的application可能给资源还回到集群,如果他不在使用或过后还请求他们当有这样需求时.这个特性非常有用如果多个共享资源在你的集群中.

这个特性默认是禁用,在粗粒度集群管理是可用,如standalone mode, YARN mode, 和Mesos coarse-grained 模式.

配置和设置

使用这个特性有两个一定要调整.1,你application一定设置park.dynamicAllocation.enabled 为true.2 你必须设置一个 external shuffle服务在每个 worker node 在同一个集群中并且设置 spark.shuffle.service.enabled 为 true在你的application. external shuffle服务目的是允许executors 移除没有删除的shuffle 文件写通过他们(更多细节描述在下边).这个方式设置这个服务调整通过 集群管理.

在standalone 模式,简单开始 在你的workers 使用配置 spark.shuffle.service.enabled为 true.

在Mesos coarse-grained 模式,运行$SPARK_HOME/sbin/start-mesos-shuffle-service.sh 在所有slave nodes用spark.shuffle.service.enabled设置为true.例如,你可能这样做通过Marathon.

在Yarn模式可以查看使用说明

所有其它相关配置是可选的并且在the spark.dynamicAllocation.*spark.shuffle.service.*下.更多细节查看配置页面.

资源分配策略

在高层次,Spark应该放弃executors当他们不在使用并且获得executors 当需要时.因为没有明确预测一个executor即将被移除运行的任务在不久将来,或是否一个新的executor 将要被加入将要空置,我们需要一组试探来决定什么时来移动和请求executors.

请求策略

用动态分配的Spark Application开始请求额外的executors当他有待处理任务在等来调度.这个条件必需意味着已存在executors不足同时处理所有任务,它他们已经提交但是没有完成.

Spark请求executors 是轮询.实际请求被触发当有待处理任务在spark.dynamicAllocation.schedulerBacklogTimeout 后,然后再次触发每个spark.dynamicAllocation.sustainedSchedulerBacklogTimeout 之后,如果待处理队列存在.另外,executors 的数量请求在每个轮询以指数增加相对上次轮询.例如,application将要增加1个executor 在第一次轮询,然后是2,4,8个executor, 依此类推.

指数增加策略动机有两个:1,application 应该请求executors 在开始时要谨慎,以防它结果仅有几个额外的executors有够了.这也回应了TCP 启动慢. 2, application 应该可以增加资源利用在及时方式,防止它生产很多实现需要用的executors .

移除策略

移除executors策略非常简单.spark application移除executor 当它已经空闲超过spark.dynamicAllocation.executorIdleTimeout设置的时间.注意:在大多数情况下,这个条件与请求条件互斥,在那样情况下executor 不应该空闲如果有待处理任务在被安排.

优雅关闭Executors

在动态分配之前,Spark executor 退出当失败或当关联的application也退出.在这种场景,所有executor 关联的状态不在需要并且可以安全丢弃. 使用动态分配,然而 ,application仍然运行当执行者明确移除.如果应用试图访问存储状态里边或通过executor写,它会必须执行重新计算状态. 因此,Spark需要一个机制来优雅关闭executor 通过保存它的状态在删除之前.

这个需求对于shuffles非常重要.在shuffle过程中,Spark executor 首先写它自己map输出到本地磁盘,然后作为这些文件的服务器当其它executors 试图获得时. 在掉队情况下,它运行时间比其它更长,动态分配可能移除executor 在shuffle完成之前,在这样例子中,shuffle 文件写通过那个executor需要做不必要的再次计算.

保留shuffle 文件方案用在扩展shuffle服务,在Spark1.2里有介绍.这个服务涉及一个长时运行进程,它运行在集群你Spark application每个node和他们的executors.如果这个服务开启, Spark executors会获取shuffle 文件从这个服务而不是他们彼此.这意味着任何suffle状态被executor 写可能继续服用在executor生命周期外.

除了写shuffle文件之外, executors 也缓存数据在磁盘或内存.当executor被移除,既然这样,所有的缓存数据不能再被访问.为了减轻这样,默认executor包含缓存数据是决不删除.你可以配置这个行为用spark.dynamicAllocation.cachedExecutorIdleTimeout.在未来版本,缓存数据可能保留通过堆外存储像 external shuffle 服务保存shuffle 文件.

Application内部调度

Spark application(SparkContext实例)内,多个并行job同时运行,如果他们从不同线程提交.通过"job",在这部分,我们打算一个Spark action(像. save, collect)和任意任务,需要运行评估那个action. Spark调度是全线程安全并且支持使用开启应用服务多个请求(如,多个用户查询).

默认,Spark调度运行job以FIFO方式.每个job是被分成"stage"(如map和reduce阶段),并且首个job是先获得所有可用资源当它的stages任务启动,然后 是第二个job优先获得,等等.如果jobs队列中最前不需要使用集群全部资源 ,后边的jobs就能马上启动,但是如果job队列任务很大,后边的队列可能有显著延时.

从Spark0.8开始,可以配置job公之间公平分配.在公平分配下,Spark分配任务在jobs之间是"轮询"方式,导致所有job获得大约相同群集资源份额. 这意味着小job提交,在此期间大job能运行开始接收立刻并且 仍然获得好的回应时间,不需要等待长job结束.这种模式最适合多用户配置.

打开公平调度,仅设置spark.scheduler.mode属性为FAIR当配置SparkContexnt时.

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.set("spark.scheduler.mode", "FAIR")
val sc = new SparkContext(conf)

公平调度池

公平调度也支持把job分组到pools中,并且 配置不同的调度选项(如.weight)对每个pool.这是非常有用的创建"高优先"池给更重要的job,例如,或每个用户job分组在一起,无论用户有多少个并发jobs,均给用户一样配额.这个方法仿照Hadoop 公平调度.

不需要任何干预,新提交的jobf进入默认pool,并且job pool可以被设置通过增加spark.scheduler.pool"本地属性"给提交它们线程中SparkContext. 需要下边操作:

// Assuming sc is your SparkContext variable
sc.setLocalProperty("spark.scheduler.pool", "pool1")

设置完本地属性,在这个线程(在这个线程中被调用RDD.save, count,collect等等)中所有提交job将要使用这个pool名字.这个设置是每个线程非常容易代表同一个用户使一个线程运行多个job.如果你想要清除pool,线程关联的,简单调用:

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

默认Pools行为

默认,每个pool获得集群(也等同于在默认池里的每个job)相同份额,但是在里边的每个pool,jobs运行是用FIFO 顺序.例如,如果你为每个用户创建一个线程池,这意味着每个用户会在集群中获得相同资源,并且每个用户的查询会以顺序运行,代替晚查询用户使用早运行用户的资源.

配置Pool属性

专门pool属性也可以通过配置文件修改.每个pool支持3个属性.

  • schedulingMode: 可以是FIFO 或FAIR, 来控制pool 中job是彼此后边排队还是公平配置共享pool资源
  • weight: 控制集群中池相对其它池份额.默认,所有池weight为1.如果你指定weight为2, 例如,它会有倍资源比其它运行的池.设置高weight像1000,本质上也使实现不同pool的优先级成为可能, weight-1000池会总是先获得启动任务,无论什么时候他的job运行.
  • minShare: 除了weight,每个pool可以指定最小份额(像cpu核数),管理员可以拥有.公平调度总是试图满足活跃的pool最小份额在重新分配额外资源之前通过权重. minShare 属性可以成放心另一种方式保证 pools可以总是获得确定数量的资源 (像10核)非常快,无需要设置优先级给集群中其它部分.默认每个pool=0.

pool属性可以通过创建xml文本来配置,类似于 conf/fairscheduler.xml.tmplate,并且或者放文件名为fairscheduler.xml到类路径,或者设置spark.scheduler.allocation.file的属性在SparkConfig

conf.set("spark.scheduler.allocation.file", "/path/to/file")

XML文件格式是简单的 元素为每个pool,用不同元素在为不同配置.例如

<?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>

完整例子在conf/fairscheduler.xml.template中.注意任意pools没有配置在 XML 文件中将为默认值对所有设置.(调度模式为FIFO,weigth 1, minShare 0).

调度使用JDBC 连接器

设置公平调度给JDBC client session,用户可以设置spark.sql.thriftserver.scheduler.pool变量

SET spark.sql.thriftserver.scheduler.pool=accounting;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值