Spark Executor Driver资源调度汇总
一、简介
于Worker Actor于,每次LaunchExecutor这将创建一个CoarseGrainedExecutorBackend流程。Executor和CoarseGrainedExecutorBackend是1对1的关系。也就是说集群里启动多少Executor实例就有多少CoarseGrainedExecutorBackend进程。
那么究竟是怎样分配Executor的呢?怎么控制调节Executor的个数呢?
二、Driver和Executor资源调度
以下主要介绍一下Spark Executor分配策略:
我们仅看。当Application提交注冊到Master后,Master会返回RegisteredApplication,之后便会调用schedule()这种方法,来分配Driver的资源。和启动Executor的资源。
schedule()方法是来调度当前可用资源的调度方法,它管理还在排队等待的Apps资源的分配。这种方法是每次在集群资源发生变动的时候都会调用,依据当前集群最新的资源来进行Apps的资源分配。
Driver资源调度:
// First schedule drivers, they take strict precedence over applications
val shuffledWorkers = Random.shuffle(workers) // 把当前workers这个HashSet的顺序随机打乱
for (worker <- shuffledWorkers if worker.state == WorkerState.ALIVE) { //遍历活着的workers
for (driver <- waitingDrivers) { //在等待队列中的Driver们会进行资源分配
if (worker.memoryFree >= driver.desc.mem && worker.coresFree >= driver.desc.cores) { //当前的worker内存和cpu均大于当前driver请求的mem和cpu。则启动
launchDriver(worker, driver) //启动Driver 内部实现是发送启动Driver命令给指定Worker。Worker来启动Driver。
waitingDrivers -= driver //把启动过的Driver从队列移除
}
}
}
Executor资源调度:
val spreadOutApps = conf.getBoolean("spark.deploy.spreadOut", true)
在介绍之前我们先介绍一个概念,
该app在每一个slave要占用的内存 (executor.memory默认512M)大
这种才算是对App可用的Worker。
/**
* Can an app use the given worker? True if the worker has enough memory and we haven't already
* launched an executor for the app on it (right now the standalone backend doesn't like having
* two executors on the same worker).
*/
def canUse(app: ApplicationInfo, worker: WorkerInfo): Boolean = {
worker.memoryFree >= app.desc.memoryPerSlave && !worker.hasExecutor(app)
}
SpreadOut分配策略:
以下看看,默认的spreadOutApps模式启动App的过程:
// Right now this is a very simple FIFO scheduler. We keep trying to fit in the first app
// in the queue, then the second app, etc.
if (spreadOutApps) {
// Try to spread out each app among all the nodes, until it has all its cores
for (app <- waitingApps if app.coresLeft > 0) { //对还未被全然分配资源的apps处理
val usableWorkers = workers.toArray.filter(_.state == WorkerState.ALIVE)
.filter(canUse(app, _)).sortBy(_.coresFree).reverse //依据core Free对可用Worker进行降序排序。
val numUsable = usableWorkers.length //可用worker的个数 eg:可用5个worker
val assigned = new Array[Int](numUsable) //候选Worker,每一个Worker一个下标,是一个数组,初始化默认都是0
var toAssign = math.min(app.coresLeft, usableWorkers.map(_.coresFree).sum)//还要分配的cores = 集群中可用Worker的可用cores总和(10)。 当前未分配core(5)中找最小的
var pos = 0
while (toAssign > 0) {
if (usableWorkers(pos).coresFree - assigned(pos) > 0) { //以round robin方式在全部可用Worker里推断当前worker空暇cpu是否大于当前数组已经分配core值
toAssign -= 1
assigned(pos) += 1 //当前下标pos的Worker分配1个core +1
}
pos = (pos + 1) % numUsable //round-robin轮询寻找有资源的Worker
}
// Now that we've decided how many cores to give on each node, let's actually give them
for (pos <- 0 until numUsable) {
if (assigned(pos) > 0) { //假设assigned数组中的值>0,将启动一个executor在。指定下标的机器上。
val exec = app.addExecutor(usableWorkers(pos), assigned(pos)) //更新app里的Executor信息
launchExecutor(usableWorkers(pos), exec) //通知可用Worker去启动Executor
app.state = ApplicationState.RUNNING
}
}
}
} else {
非SpreadOut分配策略:
。
奉献当前Worker所有资源。(Ps:挨个榨干每一个Worker的剩余资源。。。。
)
} else {
// Pack each app into as few nodes as possible until we've assigned all its cores
for (worker <- workers if worker.coresFree > 0 && worker.state == WorkerState.ALIVE) {
for (app <- waitingApps if app.coresLeft > 0) {
if (canUse(app, worker)) { //直接问当前worker是有空暇的core
val coresToUse = math.min(worker.coresFree, app.coresLeft) //有则取。无论多少
if (coresToUse > 0) { //有
val exec = app.addExecutor(worker, coresToUse) //直接启动
launchExecutor(worker, exec)
app.state = ApplicationState.RUNNING
}
}
}
}
}
}
三、总结:
2、针对同一个App。每一个Worker里仅仅能有一个针对该App的Executor存在。切记。
假设想让整个App的Executor变多,设置SPARK_WORKER_INSTANCES。让Worker变多。
3、Executor的资源分配有2种策略:
3.1、SpreadOut :一种以round-robin方式遍历集群全部可用Worker。分配Worker资源。来启动创建Executor的策略,优点是尽可能的将cores分配到各个节点。最大化负载均衡和高并行。
3.2、非SpreadOut:会尽可能的依据每一个Worker的剩余资源来启动Executor,这样启动的Executor可能仅仅在集群的一小部分机器的Worker上。这样做对node较少的集群还可以,集群规模大了。Executor的并行度和机器负载均衡就不可以保证了。
行文仓促,如有不正之处,请指出,欢迎讨论 :)
补充:
1、关于: 一个App一个Worker为什么仅仅有同意有针对该App的一个Executor 究竟这样设计为何? 的讨论:
连城404:Spark是线程级并行模型。为什么须要一个worker为一个app启动多个executor呢?
朴动_zju:一个worker相应一个executorbackend是从mesos那一套迁移过来的,mesos下也是一个slave一个executorbackend。我理解这里是能够实现起多个,但起多个貌似没什么优点,并且添加了复杂度。
CrazyJvm from=main" style="line-height:21px; text-decoration:none; color:rgb(10,140,210); background-color:rgb(250,250,250)">
从Yarn的角度考虑的话,一个Worker能够相应多个executorbackend,正如一个nodemanager相应多个container。 @OopsOutOfMemory
OopsOutOfMemory:回复@连城404:
假设一个executor太大且装的对象太多。会导致GC非常慢,多几个Executor会降低full gc慢的问题。 see this post http://t.cn/RP1bVO4(今天
11:25)
连城404:回复@OopsOutOfMemory:哦。这个考虑是有道理的。
一个workaround是单台机器部署多个worker。worker相对来说比較便宜。
JerryLead:回复@OopsOutOfMemory:看来都还在变化其中,standalone
和 YARN 还是有非常多不同,我们暂不下结论 (今天 11:35)
JerryLead:问题開始变得复杂了,是提高线程并行度还是提高进程并行度?我想
Spark 还是优先选择前者,这样 task 好管理。并且 broadcast,cache 的效率高些。后者有一些道理。但參数配置会变得更复杂,各有利弊吧
(今天 11:40)
未完待续。。
。
传送门:@JerrLead https://github.com/JerryLead/SparkInternals/blob/master/markdown/1-Overview.md
——EOF——
原创文章。转载请注明来自:http://blog.csdn.net/oopsoom/article/details/38763985
Spark Executor Driver资源调度汇总的更多相关文章
- Spark Executor Driver资源调度小结【转】
一.引子 在Worker Actor中,每次LaunchExecutor会创建一个CoarseGrainedExecutorBackend进程,Executor和CoarseGrainedExecut ...
- Spark的Driver节点和Executor节点
转载自:http://blog.sina.com.cn/s/blog_15fc03d810102wto0.html 1.驱动器节点(Driver) Spark的驱动器是执行开发程序中的 main方法的 ...
- Spark闭包 | driver & executor程序代码执行
Spark中的闭包 闭包的作用可以理解为:函数可以访问函数外部定义的变量,但是函数内部对该变量进行的修改,在函数外是不可见的,即对函数外源变量不会产生影响. 其实,在学习Spark时,一个比较难理解的 ...
- [Spark内核] 第33课:Spark Executor内幕彻底解密:Executor工作原理图、ExecutorBackend注册源码解密、Executor实例化内幕、Executor具体工作内幕
本課主題 Spark Executor 工作原理图 ExecutorBackend 注册源码鉴赏和 Executor 实例化内幕 Executor 具体是如何工作的 [引言部份:你希望读者看完这篇博客 ...
- 【Spark】榨干Spark性能-driver、exector内存突破256M
榨干Spark性能-driver.exector内存突破256M spark driver memory 256m_百度搜索 Spark executor.memory - CSDN博客 sparkd ...
- Spark Executor内幕彻底解密:Executor工作原理图、ExecutorBackend注册源码解密、Executor实例化内幕、Executor具体工作内幕
本课主题 Spark Executor 工作原理图 ExecutorBackend 注册源码鉴赏和 Executor 实例化内幕 Executor 具体是如何工作的 Spark Executor 工作 ...
- Spark Executor 概述
Spark Executor 工作原理: 1. 在CoarseGrainedExecutorBackend启动时向Driver注册Executor,其实质是注册ExecutorBackend实例,和E ...
- Spark(五十):使用JvisualVM监控Spark Executor JVM
引导 Windows环境下JvisulaVM一般存在于安装了JDK的目录${JAVA_HOME}/bin/JvisualVM.exe,它支持(本地和远程)jstatd和JMX两种方式连接远程JVM. ...
- 使用 JvisualVM 监控 spark executor
使用 JvisualVM,需要先配置 java 的启动参数 jmx 正常情况下,如下配置 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmx ...
随机推荐
- 用XAML做网页!!—导航栏
原文:用XAML做网页!!-导航栏 这次要完成的是导航栏,这是页面中比较复杂的区域. 先在 Microsoft Expression Design 中绘制导航栏的背景图案: 导出为barback.xa ...
- SWT的TableVierer的使用一
1,简单显示,表格的式样见注释中的内容 import org.eclipse.jface.viewers.TableViewer;import org.eclipse.swt.SWT;import o ...
- 最近纠结致死的一个java报错java.net.SocketException: Connection reset 终于得到解决
自从SEOTcs系统11月份24日更新了一下SEO得分算法以来,一直困扰我的一个问题出现了,java的数据job任务,在执行过程中会经常报以下的错误: “2011-12-03 18:00:32 Def ...
- Android使用应用程序资源(、颜色数组、尺寸、弦、布尔、整型)
一.Android资源分类详细解释 1.Android资源类别 Android中的资源分为两大类 : 可直接訪问的资源, 无法直接訪问的原生资源; -- 直接訪问资源 : 这些资源能够使用 R. ...
- Oracle语句集锦
创建用户并赋予dba权限 1)进入cmd 2)sqlplus / as sysdba 或者 sqlplus sys/密码 as sysdba SQL> conn sys/wcq123@orcl ...
- SQL Server Insert操作中的锁
原文:SQL Server Insert操作中的锁 这篇博文简单介绍一下在SQL Server中一条Insert语句中用到的锁. 准备数据 首先我们建立一张表Table_1,它有两列Id(bigint ...
- REST Service 基础 A further step.
1. REST Service虽然实现简单, 但也功能丰富, 可以用来实现各种基于Web的服务(service). 2. REST Service的一些特点: 1)平台无关 2) 语言无关 3)基于H ...
- graph driver-device mapper-01driver初始化
// thin device数据结构 type DevInfo struct { Hash string `json:"-"` DeviceId int `json:"d ...
- c语言移位操作
应该先看看C语言是指所有的位二进制算术位计算.即使输入的是十进制的数,在存储器存储为二进制形式. “<<”使用方法: 的格式是:a<<m,a和m式,要求m>=0. 功能: ...
- SQL:多表关联采取这一纪录迄今为止最大
笔者:iamlasong 1.需求 两个表,投递记录表和封发开拆记录表,如今想知道投递日期距最后一次封发日期天数分布情况. 对这个需求,须要先查询出投递明细,同一时候要知道相应的邮件最后一次封发情况. ...