Spark资源调度分配内幕解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
来源:互联网 发布:如何python入门 知乎 编辑:程序博客网 时间:2024/06/11 03:39
一:任务调度与资源调度的区别
1, 任务调度是通过DAGScheduler、TaskScheduler、SchedulerBackend等进行的作业调度;
2, 资源调度是指应用程序如何获得资源;
3, 任务调度是在资源调度的基础上进行的,没有资源调度那么任务调度就成为了无源之水无本之木!
二:资源调度内幕天机解密
1, 因为Master负责资源管理和调度,所以资源调度的方法shedule位于Master.scala这个类中,当注册程序或者资源发生改变的时候都会导致schedule的调用,例如注册程序的时候:
case RegisterApplication(description,driver) => {
//TODO Prevent repeated registrations from some driver
if(state== RecoveryState.STANDBY){
// ignore, don't send response
} else{
logInfo("Registering app "+ description.name)
valapp = createApplication(description,driver)
registerApplication(app)
logInfo("Registered app "+ description.name + " with ID "+ app.id)
persistenceEngine.addApplication(app)
driver.send(RegisteredApplication(app.id,self))
schedule()
}
}
2, Schedule调用的时机:每次有新的应用程序提交或者集群资源状况发生改变的时候(包括Executor增加或者减少、Worker增加或者减少等);
3, 当前Master必须是Alive的方式采用进行资源的调度,如果不是ALIVE的状态会直接返回,也就是Standby Master不会进行Application的资源调用!
if(state != RecoveryState.ALIVE) { return }
4, 使用Random.shuffle把Master中保留的集群中所有Worker的信息随机打乱;
valshuffledWorkers = Random.shuffle(workers)// Randomization helps balance drivers
其算法内部是循环随机交换所有Worker在Master缓存数据结构中的位置:
def shuffle[T,CC[X] <:TraversableOnce[X]](xs:CC[T])(implicitbf: CanBuildFrom[CC[T],T,CC[T]]):CC[T] = {
valbuf = newArrayBuffer[T] ++= xs
defswap(i1:Int, i2:Int) {
valtmp = buf(i1)
buf(i1) = buf(i2)
buf(i2) = tmp
}
for(n <- buf.length to 2by -1) {
valk = nextInt(n)
swap(n - 1,k)
}
(bf(xs) ++= buf).result
}
5, 接下来要判断所有Worker中哪些是ALIVE级别的Worker,ALIVE才能够参与资源的分配工作:
for(worker <- shuffledWorkers if worker.state== WorkerState.ALIVE) {
6, 当SparkSubmit指定Driver在Cluster模式的情况下,此时Driver会加入waitingDrivers等待列表中,在每个DriverInfo的DriverDescription中有要启动Driver时候对Worker的内存及Cores是要求等内容:
private[deploy]case class DriverDescription(
jarUrl: String,
mem:Int,
cores:Int,
supervise:Boolean,
command: Command) {
override deftoString:String =s"DriverDescription (${command.mainClass})"
}
在符合资源要求的情况下然后采用随机打乱后的一个Worker来启动Driver:
private deflaunchDriver(worker: WorkerInfo,driver: DriverInfo) {
logInfo("Launching driver "+ driver.id + " on worker "+ worker.id)
worker.addDriver(driver)
driver.worker= Some(worker)
worker.endpoint.send(LaunchDriver(driver.id,driver.desc))
driver.state= DriverState.RUNNING
}
Master发指令给Worker,让远程的Worker启动Driver:
worker.endpoint.send(LaunchDriver(driver.id,driver.desc))
7, 先启动Driver才会发生后续的一切的资源调度的模式。
8, Spark默认为应用程序启动Executor的方式是FIFO的方式,也就是所有提交的应用程序都是放在调度的等待队列中的,先进先出,只有满足了前面应用程序的资源分配的基础上才能够满足下一个应用程序资源的分配;
9, 为应用程序具体分配Executor之前要判断应用程序是否还需要分配Core,如果不需要则不会为应用程序分配Executor;
10, 具体分配Executor之前要对要求Worker必须是ALIVE的状态且必须满足Application对每个Executor的内存和Cores的要求,并且在此基础上进行排序产生计算资源由大到小的usableWorkers数据结构:
val usableWorkers =workers.toArray.filter(_.state == WorkerState.ALIVE)
.filter(worker => worker.memoryFree >= app.desc.memoryPerExecutorMB &&
worker.coresFree >= coresPerExecutor.getOrElse(1))
.sortBy(_.coresFree).reverse
在FIFO的情况下默认是spreadOutApps来让应用程序尽可能多的运行在所有的Node上:
private valspreadOutApps = conf.getBoolean("spark.deploy.spreadOut",true)
11, 为应用程序分配Executors有两种方式,第一种方式是尽可能在集群的所有Worker上分配Executor,这种方式往往会带来潜在的更好的数据本地性;
12, 具体在集群上分配Cores的时候会尽可能的满足我们的要求:
varcoresToAssign = math.min(app.coresLeft,usableWorkers.map(_.coresFree).sum)
13, 如果是每个Worker下面只能够为当前的应用程序分配一个Executor的话,每次是分配一个Core!
// If we are launching one executor per worker, then every iteration assigns 1 core
// to the executor. Otherwise, every iteration assigns cores to a new executor.
if (oneExecutorPerWorker) {
assignedExecutors(pos) = 1
} else{
assignedExecutors(pos) += 1
}
14, 准备具体要为当前应用程序分配的Executor信息后,Master要通过远程通信发指令给Worker来具体启动ExecutorBackend进程:
worker.endpoint.send(LaunchExecutor(masterUrl,
exec.application.id,exec.id,exec.application.desc,exec.cores,exec.memory))
15, 紧接着给我们应用程序的Driver发送一个ExecutorAdded的信息:
exec.application.driver.send(
ExecutorAdded(exec.id,worker.id,worker.hostPort,exec.cores,exec.memory))
- Spark资源调度分配内幕解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
- 第31课: Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
- Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
- day31:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度
- Spark资源调度分配解密
- 大数据IMF传奇行动绝密课程第31课:Spark资源调度分配内幕天机彻底解密
- spark资源调度分配
- 4.master资源调度源码分析(Driver调度和Application调度(两种))
- Spark资源调度分配原理
- Spark on Yarn资源调度源码解析
- Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法
- spark资源调度流程总结
- spark调度系列----1. spark stanalone模式下Master对worker上各个executor资源的分配
- Spark Executor Driver资源调度小结
- Spark Executor Driver资源调度小结
- Spark Executor Driver资源调度小结
- Spark Executor Driver资源调度小结
- 甘特图的资源调度
- Android activity 中如何获取webview 中加载的html中输入框的值
- qml中调用js中的函数
- 20个常用正则表达式
- 网站微信扫码支付java开发
- tmux 2.1 set mouse on
- Spark资源调度分配内幕解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结
- python题目-----Python里面如何生成随机数
- 判断日期是不是今天/昨天/前天
- Ubuntu16.04 安装常用软件
- 合唱团
- uva11988 broken keyboard (悲剧文本)
- Android中MediaRecorder类录制视频、音频详解
- 在Android Studio中生成.h头文件
- 解决Jenkins上git出现Timeout的问题