Spark动态分配资源

本文详细介绍了Spark的动态资源分配,包括作业调度的Overview、不同application间的资源调度、动态资源分配的启用和策略,以及如何释放不使用的executor。在Spark 1.2以后,动态资源分配允许executor的申请和释放,提高资源利用率。启用external shuffle service可以保护executor的shuffle文件,确保安全删除。资源分配策略包括根据pending任务数量指数级申请资源和删除长时间未使用的executor。在动态分配下,通过external shuffle service解决executor释放后的数据访问问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark动态分配资源

标签(空格分隔): spark


作业调度(Job Scheduling)

OverView

  • 在一个集群中的每一个spark application(一个sparkContext的实例)维持着一系列独立的executor集合。集群管理着这些spark application之间的资源调度。
  • 在一个spark application之内,可能同时运行着多个job,spark使用公平调度器来为这些job分配资源。

不同application之间的资源调度

  • spark application维持着一些独立的executor jvms,这些jvm用于applcaiton的数据存储和task的运行。
  • 在不同applicationzh 之间分配资源的最简单的方案是使用静态资源分配,即每一个application给予一个最大的可用资源,在这个applicaiton的生命周期中,这部分资源都不会被释放。
    • standalone模式:在此模式下,applicaiton会按照FIFO的顺序执行,在执行时,applicaiton会尝试使用所有的可用节点.可以通过参数spark.core.max设置,或者通过spark.deploy.defaultCores设置使用的核数,最后,对于每个核的内存控制,使用spark.executor.memeory进行控制。
    • Mesos模式:在此模式下,将spark.mesos.coarse设置为true来启用这种粗粒度的控制方式,和standalone模式一样,使用spark.core.maxspark.executor.memory来分别控制core和memory。
    • Yarn模式:在这种模式下,使用--num-executors来设置分配给这个applicaiton的executor,使用--executor-memory来是指每个executor的内存,使用--executor-cores来设置每个executor的核数。
    • 在Mesos模式下,spark还可以共享一台机器上不同的core,但是,所有的模式下,内存都是不可共享的,

动态资源分配

  • Spark1.2之后,有了动态分配资源的特性,每个applicaiton从资源池里申请资源,当不再使用时,放回到资源池,可以继续被其他的applicaiton使用。
  • Spark的动态资源分配是在executor层面上进行的,也就是说,从资源池申请和放回到资源池的是一个个executor,而不会对executor内的core和memory动态分配和共享。
  • 通过修改spark/conf/spark-default.conf文件,添加spark.dynamicAllocation.enabled true来开启。

启用external shuffle service

  • 启用此服务的目的是保护executor所写的shuffle文件,以便shuffle可以安全的删除。
  • 在spark配置文件中,设置spark.shffle.service.enabled true在Yarn模式下,这个shuffle服务是通过运行在每个nodemanager上的org.apache.spark.yarn.network.YarnShuffleService实现的。通过以下步骤来启用服务。
    • 在spark的lib下找到spark--yarn-shuffle.jar文件。
    • 将这个文件加入到nodemanager的classpath。
    • 在每个节点的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>
<property>
<name>spark.shuffle.service.port</name>
<value>7337</value>
</property>
  • 重启nodeManager。

资源分配策略

请求资源策略
  • 当现有的excutor不足够同时执行已提交的task时,便会向集群申请新的executor。
  • 真正触发申请操作的是,当集群pending的task达到spark.dynamicAllocation.schedulerBacklogTimeout时间时,便会触发申请操作。然后每spark.dynamicAllocation.sustainedSchedulerBacklogTimeout秒重新检测,如果还有pending的task,再次申请资源。每次申请的资源是成指数递增的,比如,1,2,4,8这种。和tcp慢启动的原理很类似。
删除资源策略
  • spark application 删除那些经过spark.dynamicAllocation.executorIdleTimeout时间未使用的executor。

如何释放不使用的executor

  • 在动态分配资源时,当释放掉不使用的executor之后,applicaiton可能还需要访问存储在那个executor上的文件。所以,spark需要在释放executor的时候保留相关的executor状体和文件。
  • 上述的这种情况在shuffle过程中是常见的,shuffle时,每个excutor首先将自己的map输出写到自身的本地硬盘中。当别的executor想要使用时,这个executor作为server向其他executor提供数据。
  • 有可能出现这样一种情况,当shuffle还没完成时,某个executor被释放掉,这时候,如果想要使用他map的输出,就需要重复的进行计算,这是很没有必要的。
  • 解决方案是引入第三方的服务来保存这些文件和相应的状态信息。称之为extern shuffle service。这是一个在每个节点长时间独立运行的服务,独立于spark的application和executor之外。当启用这个服务时,executor通过这个服务来获取相应的文件和状态信息,而不是直接从executor上拿。

Applicaiton内的调度

  • 一个spark application(sparkContext instance)中可能同时运行着多个job。比如,通过thrift执行spark-sql时,thrift的进程是一个applicaiton,thrfit可以接受多个sql进行查询,这一个个的sql就是job。
  • 默认的调度器是FIFO的,每个job被分为不同的stage(如,map阶段和reduce阶段)在队列头的会优先执行,执行完之后才会轮到下一个job执行。
  • 可以配置使用fair scheduler,不同的job会轮转的获取集群上的资源,而不用等到前面的job都执行完毕后才能执行。通过设置spark.scheduler.mode FAIR来启用。还可以在配置sparkContext的conf来设置
val conf = new SparkConf().setMaster(...).setAppName(...)
conf.set("spark.scheduler.mode", "FAIR")
val sc = new SparkContext(conf)

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值