Spark 提交后都干了些什么?
最近做了一个 Spark 小任务,在 client 模式下运行没问题,但是换了 cluster 模式就会出现一些第三方包找不到的问题。这是由于集群只在堡垒机中放了大部分的资源和 jar 包,而其他的如数据节点等节点中缺少这些包,因此需要将这些 jar 包也动态传到数据节点。如何使项目能够获取上传到 hdfs 的第三方依赖,这就需要了解 spark 任务提交后,第三方依赖包以及 spark 程序、环境配置等资源都到了哪里,然后又经过了那些环节。
通过调试和总结,本文来进一步梳理 spark 任务提交后,这些资源 jar 包等都到了哪里,怎么被运行。
上图就是 Spark 通过 client 提交后,详细的运行情况(注:部署模式为 yarn-cluster 模式)。如果不太了解部署模式,可以参考https://zhuanlan.zhihu.com/p/332486527。
spark 任务提交后,主要分为三个阶段,下面来详细说明。
阶段一:准备阶段
(1)客户端首先向 RM 进行请求,告我 RM 我想要运行一个任务,你给我安排一下;
(2)RM 收到请求后,同意提交的该 spark 任务运行,于是登记了一下,给它分配了一个 applicationId 编号,并在 hdfs 上划分了一块地方供这个任务上传一些必须的资源(hdfs:///user/用户/.sparkStaging/applicationId);
(3)客户端收到应答后,高兴的拿到自己的 applicationId,然后把本地的资源上传到属于自己的 hdfs 空间(上传的内容有①spark 所需的 jar 包,也就是在 spark 的 home 目录下 jars 下面的包;②spark 的配置参数,会打成 sparkconf.zip 的包;③上传 spark 程序的 jar 包,就是你写的工程 jar);
(4)上传资源完毕,前期准备工作就绪,准备开始向 RM 申请资源运行任务;
阶段二:执行阶段
(5)RM 收到请求,就看了一下自己的资源队列,发现有可用的 NM,于是就给该 NM 发请求,NM 收到请求,创建容器(NM 只负责对外提供 Container,至于 RM 到底在 Container 中运行什么并不关心),并报告给 RM 容器已经创建好;
(6)RM 收到应答后,告知客户端可以运行程序了
(7)client 收到应答,发送运行的命令到 NM 的 Container 中,启动 Application Master,接下来如何运行任务就交给 Application Master 来协调了
(8)Application Master 首先从 hdfs 空间将该 application 之前上传的依赖包、配置文件、执行 jar 包下载下来,并创建 Driver;
(9)Application Master 向 RM 申请 NM 容器,准备启动 Executor;
(10)RM 调度有资源的 NM 创建 Container
(11)Application Master 在获得了 NM 容器后,发送指令在容器中启动 Executor 进程,Executor 进程启动后会向 Driver 反向注册
(12)Driver 进程会解析 spark 程序,执行 main 函数;后续一系列的 DAG 创建、Stage 划分已经 task 创建都由 Driver 来完成
(13)由于可执行任务的 Executor 在 Driver 注册了,因此 Driver 会将 task 分配到 Executor 中执行
阶段三:结束阶段
(13)Executor 结束
(14)Driver 结束
(15)Application 结束,Application Master 向 RM 注销
(16)RM、NM 继续常驻进程等待下一个任务
总结
通过这篇文章,我们应该又多了一个 spark 任务运行调试小技巧,就是可以去相应的 hdfs 目录来查看该目录下的资源、配置以及依赖包是否齐全,然后进一步分析程序运行的一些异常。
例如下面这样,我们可以发现这个 application 没有提交第三方 jar 包,只是提交了 spark 的配置文件。
版权声明: 本文为 InfoQ 作者【小舰】的原创文章。
原文链接:【http://xie.infoq.cn/article/cfde147390271e8fac83b3102】。文章转载请联系作者。
评论