热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

sparkjavajob_一篇文章搞清spark任务如何执行

本文将针对spark中的Driver和Executor讲起,简述了spark的运行流程,部署模式以及内部任务调度机制,希望针对spark任

本文将针对spark中的Driver和Executor讲起,简述了spark的运行流程,部署模式以及内部任务调度机制,希望针对spark任务执行过程进行尽可能好理解的解析

1.两个重要的主角

​在spark中,有两个重要的主角是绕不开的,driver和executor,他们的结构呈一主多从模式,driver就是那个单身狗,控制欲很强,权利也很大,每天独自一人没别的事,就想法设法的指挥着手下一堆executor到处干活。他们分工明确,组织结构简单,共同支撑起了spark强大的计算引擎。

Driver

​Spark 驱动器节点,用于执行 Spark 任务中的 main 方法,负责实际代码的执行工作。Driver 在 Spark 作业执行时主要负责:

1. 将代码逻辑转化为任务;

2. 在 Executor 之间调度任务(job);

3. 跟踪 Executor 的执行情况(task)。

Executor

​Spark 执行器节点,负责在 Spark 作业中运行具体任务,任务之间相互独立。Spark 应用启动时,Executor 节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有 Executor 点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他 Executor 节点上继续运行。Executor 有两个核心功能:

1. 负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;

2. 通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD提供内存式存储。RDD 是直接缓存在 Executor 进程内的,因此任务可以在运行时充分利用缓存数据加速运算。

Spark 运行流程

3d21869d2b767828a8f62450ed99293f.png

​不论spark以何种方式部署,在任务提交后,都先启动Driver,然后Driver向集群管理器注册应用程序,之后集群管理器根据此任务的配置文件分配Executor并启动,然后Driver等待资源满足,执行 main 函数,Spark的查询为懒执行,当执行到 action 算子时才开始真正执行,开始反向推算,根据宽依赖进行 stage 的划分,随后每一个 stage 对应一个 taskset,一个taskset 中有多个 task,task 会被分发到指定的 Executor 去执行,在任务执行的过程中,Executor 也会不断与 Driver 进行通信,报告任务运行情况。

2.spark的部署模式

2.1 spark部署类型

Spark共支持3种集群管理器,Standalone,Mesos和Yarn

Standalone:

独立模式,Spark 原生的最简单的一个集群管理器。 它可以运行在各种操作系统上,自带完整的服务,无需依赖任何其他资源管理系统,使用 Standalone 可以很方便地搭建一个集群。

Apache Mesos

Mesos也是一个强大的分布式资源管理框架,是以与Linux内核同样的原则而创建的,允许多种不同的框架部署在其上

Hadoop Yarn

Hadoop生态下的统一资源管理机制,在上面可以运行多套计算框架,如mapreduce、spark 等,根据 driver 在集群中的位置不同,部署模式可以分为 yarn-client 和 yarn-cluster。

Spark 的运行模式取决于传递给 SparkContext 的 MASTER 环境变量的值,spark在yarn上部署:

yarn-client:Driver在本地,Executor在Yarn集群,配置:--deploy-mode client

yarn-cluster:Driver和Executor都在Yarn集群,配置:--deploy-mode cluster

2.2 Yarn模式下的运行机制

当前流行的工作模式均是将spark提交到Yarn上,所以这里我们针对spark on Yarn做一下详细了解。

yarn-client 模式

​ 在YARNClient模式下,Driver在任务提交的本地机器上运行,Driver会向ResourceManager申请启动ApplicationMaster,随后ResourceManager分配container,在合适的NodeManager上启动ApplicationMaster,此时的ApplicationMaster的功能相当于一个ExecutorLaucher,只负责向ResourceManager申请Executor内存。

ResourceManager接到ApplicationMaster的资源申请后会分配container,然后

ApplicationMaster在资源分配指定的NodeManager上启动Executor进程,Executor进程启动后会向Driver反向注册。另外一条线,Driver自身资源满足的情况下,Driver开始执行main函数,之后执行Action算子时,触发一个job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,Executor注册完成后,Driver将task分发到各个Executor上执行。

361acf750f2130cabeb8efd55575e4fc.png

yarn-cluster

​ 在 YARN Cluster 模式下,任务提交后会和 ResourceManager 通讯申请启动ApplicationMaster,随后 ResourceManager 分配 container,在合适的 NodeManager上启动 ApplicationMaster,此时的ApplicationMaster 就是 Driver。

​ Driver 启动后向 ResourceManager 申请 Executor 内存,ResourceManager会分配container,然后在合适的 NodeManager 上启动 Executor 进程,Executor 进程启动后会向 Driver 反向注册。另外一条线,Driver自身资源满足的情况下,开始执行main函数,之后执行Action算子时,触发一个job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,Executor注册完成后,Driver将task分发到各个Executor上执行。

771b2e98118649ccb62bd86c7c28e1ce.png

3.Spark 任务调度

​Driver会根据用户程序准备任务,并向Executor分发任务,在这儿有几个Spark的概念需要先介绍一下:

Job:以Action算子为界,遇到一个Action方法就触发一个Job

Stage:Job的子集,一个job至少有一个stage,以shuffle(即RDD宽依赖)为界,一个shuffle划分一个stage

Task: Stage 的子集,以并行度(分区数)来衡量,分区数是多少,则有多少

个 task。

spark在具体任务的调度中,总的分两路进行:Stage级别调度和Task级别调度。Spark RDD通过转换(Transactions)算子,形成了血缘关系图DAG,最后通过行动(Action)算子,触发Job并调度执行。

DAGScheduler负责Stage级的调度,主要是将DAG切分成若干Stages,并将每个Stage打包成TaskSet交给TaskScheduler调度。

TaskScheduler负责Task级的调度,将DAGScheduler给过来的TaskSet按照指定的调度策略分发到Executor上执行

3.1 Spark Stage级调度

​Spark的任务调度是从DAG切割开始,主要是由DAGScheduler来完成。当遇到一个Action操作后就会触发一个Job的计算,并交给DAGScheduler来处理。

DAGScheduler主要做两个部分的事情:

切分stage

​DAGScheduler会根据RDD的血缘关系构成的DAG进行切分,将一个Job划分为若干Stages,具体划分策略是:从后往前,由最终的RDD不断通过依赖回溯判断父依赖是否是宽依赖,遇到一个shuffle就划分一个Stage。无shuffle的称为窄依赖,窄依赖之间的RDD被划分到同一个Stage中。划分的Stages分两类,一类叫做ResultStage,为DAG最下游的Stage,由Action方法决定,另一类叫做ShuffleMapStage,为下游Stage准备数据。

​stage任务调度本身是一个反向的深度遍历算法,以下图wordcount为例。此处只有saveAsTextFile为行动算子,该 Job 由 RDD-3 和 saveAsTextFile方法组成,根据依赖关系回溯,知道回溯至没有依赖的RDD-0。回溯过程中,RDD-2和RDD-3存在reduceByKey的shuffle,会划分stage,由于RDD-3在最后一个stage,即划为ResultStage,RDD-2,RDD-1,RDD-0,这些依赖之间的转换算子flatMap,map没有shuffle,因为他们之间是窄依赖,划分为ShuffleMapStage。

88d6347ad6e3a21b57f35e044d1bbecf.png

打包Taskset提交Stage

​ 一个Stage如果没有父Stage,那么从该Stage开始提交,父Stage执行完毕才能提交子Stage。Stage提交时会将Task信息(分区信息以及方法等)序列化并被打包成TaskSet交给TaskScheduler,一个Partition对应一个Task,另一方面TaskScheduler会监控Stage的运行状态,只有Executor丢失或者Task由于Fetch失败才需要重新提交失败的Stage以调度运行失败的任务,其他类型的Task失败会在TaskScheduler的调度过程中重试。

3.2 Spark Task 级调度

​SparkTask的调度是由TaskScheduler来完成,TaskScheduler将接收的TaskSet封装为TaskSetManager加入到调度队列中。同一时间可能存在多个TaskSetManager,一个TaskSetManager对应一个TaskSet,而一个TaskSet含有n多个task信息,这些task都是同一个stage的。

​TaskScheduler初始化后会启动SchedulerBackend,它负责跟外界打交道,接收Executor的注册信息,并维护Executor的状态,SchedulerBackend会监控到有资源后,会询问TaskScheduler有没有任务要运行,TaskScheduler会从调度队列中按照指定的调度策略选择TaskSetManager去调度运行。

​TaskSetManager按照一定的调度规则一个个取出task给TaskScheduler,TaskScheduler再交给SchedulerBackend去发到Executor上执行。

​Task被提交到Executor启动执行后,Executor会将执行状态上报给SchedulerBackend,SchedulerBackend则告诉TaskScheduler,TaskScheduler找到该Task对应的TaskSetManager,并通知到该TaskSetManager,这样TaskSetManager就知道Task的运行状态

3.3 失败重试和白名单

​对于运行失败的Task,TaskSetManager会记录它失败的次数,如果失败次数还没有超过最大重试次数,那么就把它放回待调度的Task池子中等待重新执行,当重试次数过允许的最大次数,整个Application失败。在记录Task失败次数过程中,TaskSetManager还会记录它上一次失败所在的ExecutorId和Host,这样下次再调度这个Task时,会使用黑名单机制,避免它被调度到上一次失败的节点上,起到一定的容错作用。

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[一篇文章搞清spark任务如何执行]http://www.zyiz.net/tech/detail-120141.html



推荐阅读
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 标题: ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
author-avatar
耿睿---疯子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有