apachespark-spark中的内部作业调度器如何定义用户和池

6yoyoihd  于 2021-06-03  发布在  Hadoop
关注(0)|答案(3)|浏览(393)

我很抱歉在这里有点笼统,但我对spark内部的作业调度工作有点困惑。从这里的文档中,我了解到它是hadoop公平调度器的某种实现。
我无法理解到底谁是这里的用户(linux用户、hadoop用户、spark客户机?)。我也无法理解这里的池是如何定义的。例如,在hadoop集群中,我将资源分配给了两个不同的池(让我们称它们为team1和team2)。但是在spark集群中,不同的池和池中的用户不会示例化他们自己的spark上下文吗?这又让我想到了一个问题,当我将属性设置为spark.scheduler.pool时,我要传递哪些参数。
我对驱动程序如何示例化spark上下文,然后将它们拆分为任务和作业有基本的了解。也许我完全没有抓住要点,但我真的很想了解spark的内部调度程序是如何在动作、任务和作业的上下文中工作的

mklgxw1f

mklgxw1f1#

默认情况下,spark与fifo调度程序一起工作,其中作业以fifo方式执行。
但如果你在yarn上有集群,yarn有可插入的调度器,这意味着在yarn中你可以选择调度器。如果您使用的是cdh分发的yarn,您将拥有deafolt的fair scheduler,但您也可以使用capacity scheduler。
如果您使用的是hdp分发的yarn,那么默认情况下您将拥有capacity scheduler,如果需要,您可以转到fair。
调度器如何与spark一起工作?
我假设你的Spark团在Yarn上。
当您在spark中提交作业时,它首先会命中资源管理器。现在,您的资源管理器负责所有的调度和分配资源。因此,它基本上与在hadoop中提交作业相同。
调度器是如何工作的?
公平调度是一种将资源分配给作业的方法,使所有作业在一段时间内平均获得相等的资源份额。当有一个作业正在运行时,该作业将使用整个集群。当提交其他作业时,将释放的任务槽分配给新作业,以便每个作业获得大致相同的cpu时间(使用抢占机制杀死所有使用过的任务)。与默认的hadoop调度程序(fifo)不同,它形成了一个作业队列,允许短作业在合理的时间内完成,而不需要长作业。在多个用户之间共享集群也是一种合理的方式。最后,公平共享还可以与作业优先级一起工作-优先级用作权重,以确定每个作业应获得的总计算时间的分数。
capacityscheduler的设计允许共享一个大型集群,同时为每个组织提供最低容量保证。核心思想是hadoop map reduce集群中的可用资源在多个组织之间进行划分,这些组织根据计算需求共同为集群提供资金。还有一个额外的好处是,一个组织可以访问任何多余的容量,而不被其他人使用。这为各组织提供了成本效益高的弹性。

amrnrhlw

amrnrhlw2#

spark内部使用fifo/fcfs作业调度程序。但是,当你谈论任务时,它是以循环方式工作的。如果我们把注意力集中在下面的例子上,就很清楚了:
假设spark自己队列中的第一个作业不需要使用集群中的所有资源;因此,队列中的第二个作业也将立即开始执行。现在,两个作业同时运行。为了执行整个作业,每个作业只有很少的任务要执行。假设第一个作业分配10个任务,第二个作业分配8个任务。然后,这18个任务将以抢占方式共享整个集群的cpu周期。如果你想进一步深入,让我们从执行者开始。
群集中的执行者将很少。假设数字是6。因此,在理想情况下,每个执行器将被分配3个任务,这3个任务将获得与执行器相同的cpu时间(单独的jvm)。
这就是spark内部安排任务的方式。

tyu7yeag

tyu7yeag3#

我发现官方文件非常详尽,涵盖了你的所有问题。然而,人们可能会发现从第一次开始就很难消化。
在深入研究细节之前,让我们先给出一些定义和粗略的类比。 application 是什么创造了sparkcontext sc 可能被称为使用spark submit部署的东西。 job 是spark定义中的一个动作,意思是count、collect等。
有两个主要的并且在某种意义上是独立的主题:跨 application 时间安排 application . 前者更多地涉及到资源管理器,包括spark独立的fifo-only模式以及静态和动态分配的概念。
后者,在spark内调度 application 我从你的评论中了解到,这是你的问题。让我试着描述一下在某种抽象层次上发生了什么。
假设你提交了 application 你有两个 job s

sc.textFile("..").count()   //job1
sc.textFile("..").collect() //job2

如果这段代码恰好在同一个线程中执行,那么这里就没有什么有趣的事情发生,job2及其所有任务只有在job1完成之后才能获得资源。
现在假设你有以下几点

thread1 { job1 }
thread2 { job2 }

这越来越有趣了。默认情况下,在 application 调度程序将使用先进先出(fifo)将资源分配给所有任务 job 碰巧在调度程序中显示为第一个。其他任务 job 只有当有备用核心并且没有更多的挂起任务时,才会从优先级更高的第一个获得资源 job .
现在假设你 spark.scheduler.mode=FAIR 为了你的 application . 从现在开始 job 有一种 pool 它属于我。如果你什么都不做,那么每一份工作 pool 标签为“默认”。为您的 job 您可以执行以下操作

sc.setLocalProperty("spark.scheduler.pool", "pool1").textFile("").count() // job1
sc.setLocalProperty("spark.scheduler.pool", "pool2").textFile("").collect() // job2

这里需要注意的一点是,setlocalproperty对每个线程有效,对所有派生的线程也有效。这对我们意味着什么?好吧,如果你在同一条线上,那就没有什么意义了 job 一个接一个地被处决。但是,一旦你有以下

thread1 { job1 } // pool1
thread2 { job2 } // pool2

job1和job2在资源分配的意义上变得不相关。一般来说,正确配置fairscheduler文件中的每个池,minshare>0可以确保 job 来自不同池的将有资源继续。
然而,你可以更进一步。默认情况下,在每个
pool job s是以fifo方式排队的,这种情况与我们使用fifo模式和 job 来自不同线程的。要改变你需要改变 pool 在xml文件中 <schedulingMode>FAIR</schedulingMode> .
考虑到这些,如果你 spark.scheduler.mode=FAIR 让所有的 job s落入同一个“default”池,这与使用default大致相同 spark.scheduler.mode=FIFO 还有你的 job 可以在不同的线程中启动。如果您仍然只需要一个“default”公平池,只需更改xml文件中“default”池的配置即可反映这一点。
利用 pool 你需要定义 user 这与将“spark.scheduler.pool”从适当的线程设置为适当的值相同。例如,如果 application 侦听jms,然后消息处理器可以为每个消息处理设置池标签 job 取决于它的内容。
最后,不确定字数是否比官方文件少,但希望能有所帮助:)

相关问题