为了账号安全,请及时绑定邮箱和手机立即绑定

Spark 2.x 应用提交流程

标签:
Spark

Spark的计算抽象

Spark组件间的交互流程之前,先看下它的计算抽象

1. Application

它是用户编写的spark程序,完成一个计算任务的处理.  Application = 1个Driver(驱动程序) + 一组Executor(执行程序,运行在spark节点上).

2. Job

在用户程序中,每次调用Action(行动),逻辑上会生成一个job,一个Job包含多个Stage.

3. Stage

需要shuffle的时候就会将每个Job划分为多个Stage,Stage划分的依据就是宽依赖,例如reduceByKey,groupByKey等会产生宽依赖.

Stage包括两类: ShuffleMapStage和ResultStage. 后面的Stage依赖于前面的Stage,也就是说只有前面依赖的Stage计算完毕后,后面的Stage才会运行。

ShuffleMapStage: 不是最终的Stage,后面还有其他的Stage,是以shuffle为输出,它的输入可以从外部获取,也可以是另一个ShuffleMapStage的输出. 在一个Job里面它可以由也可以没有. ShuffleMapStage的最后Task就是ShuffleMapTask

ResultStage: 是最终的Stage,它的输入可以是shuffleMapStage,也可以是外部的Stage. 在一个Job里面是至少有一个Stage(因为无论如何都要输出嘛),ResultStage的最后Task就是ResultTask

窄依赖: 指一个或多个父partition对一个子partition,只能被一个子partition使用. 窄依赖都是Map任务,不需要发生shuffle。因此,窄依赖的Task一般都会被合成在一起,构成一个Stage。

宽依赖: 指一个父partition对多个子partition,被多个子partition使用. 宽依赖需要子计算出父的partition里面的数据,然后进行shuffle, RDD的partition

4. TaskSet

基于Stage可以直接映射为TaskSet,一个TaskSet包含多个Task,一个TaskSet封装了一次需要运算的具有相同处理逻辑的Task.,默认为200个

5. Task

Task是物理节点上基本的运行单位,且Task可以并行计算.因此需要Executor启动多个线程来执行Task. Task包含两类: ShuffleMapTask和ResultTask,分别对应Stage中的ShuffleMapStage和ResultStage中的一个执行基本单元

总结

用户提交的Spakr程序,最终生成TaskSet, 而在调度时,通过TaskSetManager来管理一个TaskSet(TaskSet封装了一次相同逻辑的Task),只有一个TaskSet中所有的Task都运行完之后,才能调度下一个TaskSet中的Task区执行.


Spark核心组件的交互流程

在Standalone模式下,组件间的主要交互流程如下:

一个Application启动一个Driver

一个Driver负责跟踪管理该Application运行过程中所有的资源状态和任务状态

一个Driver管理一组Executor

一个Executor只执行属于一个Driver的Task

webp

Spark应用程序提交流程

上图总结如下:

spark -submit后: 应用程序提交 => 启动Driver进程 => 注册Application => 启动Executor进程 => 启动Task执行 => Task运行完成

上图详细如下:

1. Driver进程是怎么启动的,启动了哪些东西

在DriverClient(JVM)里面, Spark submit提交之后, 创建ClientEndpoint(和Master进行通信用的)端点, ClientEndpoint这时会给Master发个消息, 叫RequestSubmitDriver(请求提交DriverJAR包)的消息, Master接收完之后, Master中的MasterEndpoint会给Worker发一个消息, 叫LaunchDriver(启动一个Driver), 假设已经启动成功了, 那MasterEndpoint就会像DriverClient发送一个叫SubmitDriverResponse的消息(告诉Driver已经启动成功了), ClientEndpoint就会给Master发送一个RequestDriverStatus的消息, 确认下是否成功了, 如果成功了, DriverClient就退出,Driver启动成功. 回到第一步Master中的MasterEndpoint会给Worker发一个消息, 叫LaunchDriver(启动一个Driver)这里, WorkerEndpoint接到LaunchDriver消息后, 他会创建一个DriverRunner封装的类, DriverRunner会根据本地的run DriverWrapper(封装的东西)去启动一个Driver进程, 这个Driver是在这个Worker上启动的, 这个时候Driver就运行成功了.

2. 注册Application是怎么做的,注册了什么东西

在Driver中, new了一个SparkConText(我们代码上是new了一个SparkConText), 接着SparkConText创建了一个SparkEnv(它汇集了Spark链接.关联等消息组合), SparkConText再次创建了TaskScheduler(他是具体运行任务用的). 接着SparkConText会根据我们传入的--Master, 去做StandaloneSchedulerBackend(具体运行程序,具体需要资源用的)的实例化, StandaloneSchedulerBackend接着创建了一个DriverEndpoint(它是用来通信用的,主要用于发布任务的, 和Executer消息通信),StandaloneSchedulerBackend接着创建了一个ClientEndpoint(它主要是和Master通信用的), 所以在Driver中有两个RPC端点,也有两个Inbox(DriverEndpoint和ClientEndpoint), 到此时位置,SparkContext已经new完了,ClientEndpoint会向Master发送一个RegisterApplication的消息, 告诉Master,Driver已经创建完了, Master中的MasterEndpoint接到RegisterApplication要运行Driver的请求之后,MasterEndpoint就向Driver中的RegisteredApplication, 告诉它已经注册好了, 这时就注册好了.

3.Executor是怎么启动的,启动了什么东西

注册完了之后, Master就要给这个应用程序分配资源了, MasterEndpoint会向挑选好的Worker中发送一个LaunchExecutor的消息, 同时向Driver发送一个ExecutorAdded的消息, 意思就是告诉Driver, Master正在给你申请Executor, 这是Executor还没建成. Woker接到LaunchExecutor的消息后, 就new了一个ExecutorRunner,ExecutorRunner就新建了一个Executor的实例(JVM), 同时, Worker中的DriverRunner就启动了Executor(也有关闭的权限), 启动完成之后, Worker中的WorkerEndpoint就向Master发送了一个ExecutorStateChanged的消息, MasterEndpoint接到这个消息之后, 就知道Executor创建且启动好了, MasterEndpoint就向Driver发送一个ExecutorUpdated的消息, 也就是告诉Driver,它要的Executor创建好了, 并且启动了, 你可以向下执行你的Task任务了, 至此为止,Executor就已经创建且启动了

4. Executor来了之后,是怎么转换成RDD,RDD是怎么转换成Task执行的

Executor启动之后,StandaloneSchedulerBackend就启动DriverEndpoint(因为在任务运行需要启动这个东西),DriverEndpoint有线程就会向ReviveOffers访问,看看有没资源,有没有资源让我的Task去运行,如果有,StandaloneSchedulerBackend就会告诉TaskScheduler,你能够把我的那些RDD创建Task运行了,DriverEndpoint就会告诉选中的Executor中的LaunchTask,去创建Task吧,CoarseGrainedExecutorBackend接收到LaunchTask的消息后,CoarseGrainedExecutorBackend就会真正的去Executor,真正的去执行这个任务.执行完了,Executor就会向告诉CoarseGrainedExecutorBackend,任务执行完了,接着CoarseGrainedExecutorBackend就会向Driver发消息,说StatusUpdate,告诉Driver当前的任务已经运行完了,同时就执行下面的Task.

5. Task执行完成之后,是怎么回调的

依旧从上面那个看看有没资源开始起循环, 最后, 所有的任务都运行完成, Driver结束, Driver结束了之后, 就告诉MasterEndpoint整个Application结束了, MasterEndpoint接收到Application结束后, 就告诉相应的Worker, 叫DriverRunner关掉Application所有的Executor, 至此整个运行结束!



作者:终生学习丶
链接:https://www.jianshu.com/p/26e8af35c548


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消