Spark Core 资源调度与任务调度(standalone client 流程描述)

Spark集群启动: 
    集群启动后,Worker会向Master汇报资源情况(实际上将Worker的资源写入到Master的HashSet数据机构中)
    一个 Worker 默认给一个 Application 启动 1 个 Executor,可以设置 --executor-cores num 来启动多个。开机启动时最好设置 spreadOut, 可以在集群中分散启动 executor。 
 
资源调度:
    实际上我们的代码会先在Driver这个进程(我们写的spark程序,打成jar包,用spark-submit来提交,local模式当我们的程序提交到集群上时,会加载并执行我们的jar包,并找到jar包中的main函数执行一遍,执行main所启动的这个进程名就是SparkSubmit,这个进程就是我们所说的Driver进程; cluster模式会在集群中找一台node,会启动一个进程执行一遍我们提交的代码,这个进程就是Driver,Driver启动之后将其信息注册到Master中,存储在ArrayBuffer中)中执行一遍,Driver这个进程中有SparkContext这个对象。代码从main函数开始执行,new SparkConf()设置我们运行Spark时的环境参数(还可以通过spark-submit -- 加上参数来设置),newSparkContext()(在源码的700多行左右),创建DAGSchedulerTaskScheduler,TaskScheduler另启动一个线程将Application注册到Master中(是放到Master中的ArrayBuffer的数据结构中,当ArrayBuffer中有信息之后,Master会调用自己的schedule()方法,schedule会为当前的Application申请资源,此时master会找一些空闲的Worker,并在Worker上启动Executor进程,Executor启动完成之后会反向注册TaskScheduler
 
现在Application有了,有了资源后,开始进行任务的调度
 
任务调度: (此时代码的第二行(new SparkContext(conf))已经执行完毕)     
1.Action类型的算子触发job的执行。源码中调用了SparkContext的runJob()方法,跟进源码发现底层调用的是DAGScheduler的runJob()方法。
   DAGScheduler会将我们的job按照宽窄依赖划分为一个个stage,每个stage中有一组并行计算的task,每一个task都可以看做是一个”pipeline”,,这个管道里面数据是一条一条被计算的,每经过一个RDD会经过一次处理,RDD是一个抽象的概念里面存储的是一些计算的逻辑,每一条数据计算完成之后会在shuffle write过程中将数据落地写入到我们的磁盘中。
 
2.stage划分完之后会以TaskSet的形式提交给我们的TaskScheduler。
    源码中TaskScheduler.submit.tasks(new TaskSet())只是一个调用方法的过程而已。我们口述说是发送到TaskScheduler。TaskScheduler接收到TaskSet之后会进行遍历,每遍历一条调用launchTask()方法,launchTask()根据数据本地化的算法发送task到指定的Executor中执行。task在发送到Executor之前首先进行序列化,Executor中有ThreadPool,ThreadPool中有很多线程,在这里面来具体执行我们的task。
 
3.TaskScheduler和Executor之间有通信(Executor有一个邮箱(消息循环体CoresExecutorGraintedBackend)),Executor接收到task
    Executor接收到task后首先将task反序列化,反序列化后将这个task变为taskRunner(new taskRunner),并不是TaskScheduler直接向Executor发送了一个线程,这个线程是在Executor中变成的。然后这个线程就可以在Executor中的ThreadPool中执行了。
 
4.Executor接收到的task分为maptask 和 reducetask
    map task 和 reduce task,比如这里有三个stage,先从stage1到stage2再到stage3,针对于stage2来说,stage1中的task就是map task ,stage2中的task就是reduce task,针对stage3来说...map task 是一个管道,管道的计算结果会在shuffle write阶段数据落地,数据落地会根据我们的分区策略写入到不同的磁盘小文件中,注意相同的key一定写入到相同的磁盘小文件中),map端执行完成之后,会向Driver中的DAGScheduler对象里面的MapOutputTracker发送了一个map task的执行状态(成功还是失败还有每一个小文件的地址)。然后reduce task开始执行,reduce端的输入数据就是map端的输出数据。那么如何拿到map端的输出数据呢?reduce task会先向Driver中MapOutPutTracker请求这一批磁盘小文件的地址,拿到地址后,由reduce task所在的Executor里面的BlockManagerMap task 所在的Executor先建立连接,连接是由ConnectionManager负责的,然后由BlockTransformService去拉取数据,拉取到的数据作为reduce task的输入数据(如果使用到了广播变量,reduce task 或者map task 它会先向它所在的Executor中的BlockManager要广播变量,没有的话,本地的BlockManager会去连接Driver中的BlockManagerMaster,连接完成之后由BlockTransformService将广播变量拉取过来)Executor中有了广播变量了,task就可以正常执行了。
 

【细节一:提交时的容错能力】

TaskScheduler提交task如果发生了失败,默认会重试三次,如果依然失败,那么则认为这个task就失败了,这时会进行stage重试,DAGScheduler会重新发送TaskSet给TaskScheduler,默认会重试四次,如果四次后依然失败,则认为job失败。因此一个task默认情况下重试3*4=12次

如果task失败是由于shuffle file not find造成的,那么TaskScheduler是不负责重试的,直接进行stage重试。

【细节二:重试机制的问题】

前提:Task的逻辑是将处理的数据结果放入到数据库中

如果一个Task提交到百分之七十五,然后失败了,这时候会重试,那么有执行了一次task,这时候就会有脏数据的产生。

以上问题如何去解决?

1.关闭重试机制。
2.在数据库中设置主键,这时候如果重复提交,那么会失败,也就避免了脏数据的产生。

Spark Core 资源调度与任务调度(standalone client 流程描述)

Spark集群启动: 
    集群启动后,Worker会向Master汇报资源情况(实际上将Worker的资源写入到Master的HashSet数据机构中)
    一个 Worker 默认给一个 Application 启动 1 个 Executor,可以设置 --executor-cores num 来启动多个。开机启动时最好设置 spreadOut, 可以在集群中分散启动 executor。 
 
资源调度:
    实际上我们的代码会先在Driver这个进程(我们写的spark程序,打成jar包,用spark-submit来提交,local模式当我们的程序提交到集群上时,会加载并执行我们的jar包,并找到jar包中的main函数执行一遍,执行main所启动的这个进程名就是SparkSubmit,这个进程就是我们所说的Driver进程; cluster模式会在集群中找一台node,会启动一个进程执行一遍我们提交的代码,这个进程就是Driver,Driver启动之后将其信息注册到Master中,存储在ArrayBuffer中)中执行一遍,Driver这个进程中有SparkContext这个对象。代码从main函数开始执行,new SparkConf()设置我们运行Spark时的环境参数(还可以通过spark-submit -- 加上参数来设置),newSparkContext()(在源码的700多行左右),创建DAGSchedulerTaskScheduler,TaskScheduler另启动一个线程将Application注册到Master中(是放到Master中的ArrayBuffer的数据结构中,当ArrayBuffer中有信息之后,Master会调用自己的schedule()方法,schedule会为当前的Application申请资源,此时master会找一些空闲的Worker,并在Worker上启动Executor进程,Executor启动完成之后会反向注册TaskScheduler
 
现在Application有了,有了资源后,开始进行任务的调度
 
任务调度: (此时代码的第二行(new SparkContext(conf))已经执行完毕)     
1.Action类型的算子触发job的执行。源码中调用了SparkContext的runJob()方法,跟进源码发现底层调用的是DAGScheduler的runJob()方法。
   DAGScheduler会将我们的job按照宽窄依赖划分为一个个stage,每个stage中有一组并行计算的task,每一个task都可以看做是一个”pipeline”,,这个管道里面数据是一条一条被计算的,每经过一个RDD会经过一次处理,RDD是一个抽象的概念里面存储的是一些计算的逻辑,每一条数据计算完成之后会在shuffle write过程中将数据落地写入到我们的磁盘中。
 
2.stage划分完之后会以TaskSet的形式提交给我们的TaskScheduler。
    源码中TaskScheduler.submit.tasks(new TaskSet())只是一个调用方法的过程而已。我们口述说是发送到TaskScheduler。TaskScheduler接收到TaskSet之后会进行遍历,每遍历一条调用launchTask()方法,launchTask()根据数据本地化的算法发送task到指定的Executor中执行。task在发送到Executor之前首先进行序列化,Executor中有ThreadPool,ThreadPool中有很多线程,在这里面来具体执行我们的task。
 
3.TaskScheduler和Executor之间有通信(Executor有一个邮箱(消息循环体CoresExecutorGraintedBackend)),Executor接收到task
    Executor接收到task后首先将task反序列化,反序列化后将这个task变为taskRunner(new taskRunner),并不是TaskScheduler直接向Executor发送了一个线程,这个线程是在Executor中变成的。然后这个线程就可以在Executor中的ThreadPool中执行了。
 
4.Executor接收到的task分为maptask 和 reducetask
    map task 和 reduce task,比如这里有三个stage,先从stage1到stage2再到stage3,针对于stage2来说,stage1中的task就是map task ,stage2中的task就是reduce task,针对stage3来说...map task 是一个管道,管道的计算结果会在shuffle write阶段数据落地,数据落地会根据我们的分区策略写入到不同的磁盘小文件中,注意相同的key一定写入到相同的磁盘小文件中),map端执行完成之后,会向Driver中的DAGScheduler对象里面的MapOutputTracker发送了一个map task的执行状态(成功还是失败还有每一个小文件的地址)。然后reduce task开始执行,reduce端的输入数据就是map端的输出数据。那么如何拿到map端的输出数据呢?reduce task会先向Driver中MapOutPutTracker请求这一批磁盘小文件的地址,拿到地址后,由reduce task所在的Executor里面的BlockManagerMap task 所在的Executor先建立连接,连接是由ConnectionManager负责的,然后由BlockTransformService去拉取数据,拉取到的数据作为reduce task的输入数据(如果使用到了广播变量,reduce task 或者map task 它会先向它所在的Executor中的BlockManager要广播变量,没有的话,本地的BlockManager会去连接Driver中的BlockManagerMaster,连接完成之后由BlockTransformService将广播变量拉取过来)Executor中有了广播变量了,task就可以正常执行了。
 

【细节一:提交时的容错能力】

TaskScheduler提交task如果发生了失败,默认会重试三次,如果依然失败,那么则认为这个task就失败了,这时会进行stage重试,DAGScheduler会重新发送TaskSet给TaskScheduler,默认会重试四次,如果四次后依然失败,则认为job失败。因此一个task默认情况下重试3*4=12次

如果task失败是由于shuffle file not find造成的,那么TaskScheduler是不负责重试的,直接进行stage重试。

【细节二:重试机制的问题】

前提:Task的逻辑是将处理的数据结果放入到数据库中

如果一个Task提交到百分之七十五,然后失败了,这时候会重试,那么有执行了一次task,这时候就会有脏数据的产生。

以上问题如何去解决?

1.关闭重试机制。
2.在数据库中设置主键,这时候如果重复提交,那么会失败,也就避免了脏数据的产生。

Spark Core 资源调度与任务调度(standalone client 流程描述)的更多相关文章

  1. Spark Core_资源调度与任务调度详述

    转载请标明出处http://www.cnblogs.com/haozhengfei/p/0593214ae0a5395d1411395169eaabfa.html Spark Core_资源调度与任务 ...

  2. Spark中资源调度和任务调度

    Spark比MR快的原因 1.Spark基于内存的计算 2.粗粒度资源调度 3.DAG有向无环图:可以根据宽窄依赖划分出可以并行计算的task 细粒度资源调度 MR是属于细粒度资源调度 优点:每个ta ...

  3. 【源码学习之spark core 1.6.1 standalone模式下的作业提交】

    说明:个人原创,转载请说明出处 http://www.cnblogs.com/piaolingzxh/p/5656876.html 未完待续

  4. spark 图文详解:资源调度和任务调度

    讲说spark的资源调度和任务调度,基本的spark术语,这里不再多说,懂的人都懂了... 按照数字顺序阅读,逐渐深入理解:以下所有截图均为个人上传,不知道为什么总是显示别人的QQ,好尴尬,无所谓啦, ...

  5. 【Spark-core学习之六】 Spark资源调度和任务调度

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...

  6. spark中资源调度任务调度

    在spark的资源调度中 1.集群启动worker向master汇报资源情况 2.Client向集群提交app,向master注册一个driver(需要多少core.memery),启动一个drive ...

  7. Spark 资源调度 与 任务调度

    Spark 资源调度与任务调度的流程(Standalone): 启动集群后, Worker 节点会向 Master 节点汇报资源情况, Master掌握了集群资源状况. 当 Spark 提交一个 Ap ...

  8. 大话Spark(5)-三图详述Spark Standalone/Client/Cluster运行模式

    之前在 大话Spark(2)里讲过Spark Yarn-Client的运行模式,有同学反馈与Cluster模式没有对比, 这里我重新整理了三张图分别看下Standalone,Yarn-Client 和 ...

  9. 【Spark篇】---Spark资源调度和任务调度

    一.前述 Spark的资源调度是个很重要的模块,只要搞懂原理,才能具体明白Spark是怎么执行的,所以尤其重要. 自愿申请的话,本文分粗粒度和细粒度模式分别介绍. 二.具体 Spark资源调度流程图: ...

随机推荐

  1. 团队开发--NABCD

    团队成员介绍: 李青:绝对的技术控,团队中扮演“猪”的角色,勤干肯干,是整个团队的主心骨,课上紧跟老师的步伐,下课谨遵老师的指令,课堂效率高,他的编程格言“没有编不出来的程序,只有解决不了的bug”. ...

  2. c++团队作业工作笔记

    这周时间还比较充裕,所以就有较多的时间来投入团队作业之中. emmmm,由于组长那边感觉完全没动,于是我完成了选英雄的UI界面,到时候给button加上信号就没什么问题. 虽然界面比较简单,但是还是花 ...

  3. 404 Note Found 现场编程

    目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...

  4. Firefox必备的24款web开发插件

    from: 软件过滤: 排序:收录时间 | 浏览数 网页开发FireFox插件 Firebug Firebug是Firefox下的一款开发类插件,现属于Firefox的 五星级强力推荐插件之一.它集H ...

  5. PAT 甲级 1023 Have Fun with Numbers

    https://pintia.cn/problem-sets/994805342720868352/problems/994805478658260992 Notice that the number ...

  6. Java Map 在put值时value值不被覆盖

    一.问题描述 最近在代码开发中遇到一个问题,在往Map中put文件路径值然后把Map放到List中去时,遇到问题是Map的后一个值总是把前一个值覆盖,导致最后Map中只有一个值. 二.解决办法(有如下 ...

  7. 【Linux笔记】GRUB配置与应用,启动故障分析解决。

    一.GRUB启动位置 GRUB是现今大多数Linux系统采用的自举程序,这里先来看一下Linux的程序顺序: 执行顺序    动作 固件Firmware(CMOS/BIOS) →  POST(Pwer ...

  8. javascript如何封装函数

    通常写js组件开发的,都会用到匿名函数的写法去封装一个对象,与外界形成一个闭包的作用域.封装,全天下漫天遍野的封装,JQuery,EXT和Prototype.js封装的是javascript,jQue ...

  9. poj2299——Ultra-QuickSort

    Description In this problem, you have to analyze a particular sorting algorithm. The algorithm proce ...

  10. Qt的编程风格与规范

    Qt的编程风格与规范 来源: http://blog.csdn.net/qq_35488967/article/details/70055490 参考资料: https://wiki.qt.io/Qt ...