spark可以运行在standalone,yarn,mesos等多种模式下,当前我们用的最普遍的是yarn模式,在yarn模式下又分为client和cluster。本文接下来将分析yarn cluster下任务提交的过程。也就是回答,在yarn cluster模式下,任务是怎么提交的问题。在yarn cluster模式下,spark任务提交涉及四个角色(client, application, driver以及executor)之间的交互。接下来,将详细分析这四个角色在任务提交过程中都做了那些事。

1,client流程

Step  1:我们知道:在我们写完任务准备向集群提交spark任务时,一般是调用bin下的spark-submit脚本进行任务的提交。在完成一些环境变量和参数的准备后,最终调用spark代码库中的SparkSubmit类。

Step 2:在SparkSubmit的main函数中,通过submit,runMain然后通过YarnClusterApplication启动org.apache.spark.deploy.yarn.Client.

Step 3:在Client中,通过main,run,然后在submitApplication中,利用yarnClient向ResourceManager提交新应用以启动ApplicationMaster,其中在yarn cluster模式下启动ApplicationMaster的类是

org.apache.spark.deploy.yarn.ApplicationMaster。 至此,client完成所有的工作。

2,ApplicationMaster流程

Step1:yarn分配container运行ApplicationMaster。通过main,run,runDriver,调用startUserApplication,新建线程,运行在spark-submit --class参数指定的应用类用户代码。

Step2:ApplicationMaster等待driver完成sparkContext的初始化后,获取driver的一个ref。调用registerAM函数,利用YarnRMClient向yarn申请资源运行executor。一旦获取到container资源,在yarnAllocator中,

launcherPool线程池会将container,driver等相关信息封装成ExecutorRunnable对象,通过ExecutorRunnable启动新的container以运行executor。在次过程中,指定启动executor的类是
org.apache.spark.executor.CoarseGrainedExecutorBackend。

3,Driver流程

在ApplicationMaster的步骤1中,会新建线程运行用户端代码,并且在完成sparkcontext的初始化,其中包括dagScheduler完成job stage的切分,每个stage的任务转成化一系列的task,封装成taskset。交由taskScheduler去调用。由于这个过程比较复杂,而且非常的重要,准备稍后会单独对这个部分进行详细讲解。

4,Executor流程

在ApplicationMaster的步骤2中提到,新的container将会运行executor。在executor启动以后,会向driver发送RegisterExecutor消息告诉driver注册当前运行的executor。在driver端的CoarseGrainedSchedulerBackend中,可以看到对该消息的处理过程。在driver段感知到该消息后,driver将向executor发送RegisteredExecutor消息。executor和driver更多的细节,在稍后spark任务计算解析中,会将进行更详细的描述。

至此,client在完成使命后退出。其他三个部分也已启动起来。接下来将以spark example中的sparkPi例子来看看平常我们写的spark任务是怎么计算的。

首先把sparkPi中的代码贴出来:

问题1:何时开始运行用户的中main函数?

在前文中 ApplicationMaster流程中第一步提到:yarn分配container运行ApplicationMaster。通过main,run,runDriver,调用startUserApplication,新建线程,运行在spark-submit --class参数指定的应用类用户代码。也就是说,在这一步将运行用户写入的代码。

问题2:上述代码具体都做了些啥?

1,在SparkSession...getOrCreate函数中主要做的事情是完成sparkContext的初始化,这其中主要包括DAGScheduler,TaskSchedule的初始化等。(注:在调试过程中使用的standalone模式,并且加入extraJavaOption主要是为了便于调试executor的代码)。

2,上述代码的核心是sparkContext.parallelize(....).map(....).reduce。在parallelize函数中将新建ParallelCollectionRDD。在map中将新建MapPartitionsRDD。最后reduce是一个action(一个action对应一个Job),触发实际的计算。

3,在reduce函数中,通过调用sc.runJob->dagScheduler.runJob→submitJob提交JobSubmitted事件到DAGScheduler自己。然后调用handleJobSubmitted来处理Job提交。在handleJobSubmitted函数中,将创建ResultStage,然后根据shuffle将Job划分为不同的stage。在本例中,由于没有shuffle,将只有一个stage。最终通过submitMissingTasks将stage中的task封装成taskset,交由taskschuduler(taskScheduler.submitTasks)进行task级别的调度。

4,在TaskSchdulerImpl的submitTasks中,可以看到taskset会被进一步封装成TasksetManager,加入到schedulableBuilder中(默认使用FIFO队列进行调度)。然后driver向自己发送ReviveOffers消息。driver接收到该信息后,如果发现有空闲的executor,将该Task序列后,发送LaunchTask消息给executor。让executor去执行。

5,executor处理LaunchTask消息的代码如下:

launchTask会将task信息TaskRunner,启用线程池运行。

6,在TaskRunner的run方法中,将运行

val res = task.run(
taskAttemptId = taskId,
attemptNumber = taskDescription.attemptNumber,
metricsSystem = env.metricsSystem)
threwException = false
然后调用runTask进行运行,有两种类型的Task(ShuffleMapTask,ResultTask),本例中将运行ResultTask中的runTask方法,然后在该方法中,调用用户传入的函数代码。

7,在TaskRunner的run方法中,在完成计算后,将调用execBackend.statusUpdate(taskId, TaskState.FINISHED, serializedResult),该函数将向driver发送信息,告诉改Task已完成。

8,在driver端,如果任务正常结束,将调用taskResultGetter.enqueueSuccessfulTask。在该函数中,接着调用handleSuccessfulTask,最终DAGScheduler将向自己发送CompletionEvent事件,然后使用handleTaskCompletion来处理。如果任务正常结束,将通过

job.listener.taskSucceeded通知JobWaiter,JobWaiter完成任务结果的合并。在所有的JobWaiter中的Task都完成后,任务退出。

spark yarn cluster模式下任务提交和计算流程分析的更多相关文章

  1. Spark基本工作流程及YARN cluster模式原理(读书笔记)

    Spark基本工作流程及YARN cluster模式原理 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark基本工作流程 相关术语解释 Spark应用程序相关的几 ...

  2. Apache Spark源码走读之19 -- standalone cluster模式下资源的申请与释放

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本文主要讲述在standalone cluster部署模式下,Spark Application在整个运行期间,资源(主要是cpu core和内存)的申请与 ...

  3. [Spark内核] 第31课:Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结

    本課主題 Master 资源调度的源码鉴赏 [引言部份:你希望读者看完这篇博客后有那些启发.学到什么样的知识点] 更新中...... 资源调度管理 任务调度与资源是通过 DAGScheduler.Ta ...

  4. DEBUG模式下, 内存中的变量地址分析

    测试函数的模板实现 /// @file my_template.h /// @brief 测试数据类型用的模板实现 #ifndef MY_TEMPLATE_H_2016_0123_1226 #defi ...

  5. Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77942585 前面的博客<Android平台dalvik模式下java Ho ...

  6. Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结

    本课主题 Master 资源调度的源码鉴赏 资源调度管理 任务调度与资源是通过 DAGScheduler.TaskScheduler.SchedulerBackend 等进行的作业调度 资源调度是指应 ...

  7. 【原】Spark不同运行模式下资源分配源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Task的提交源码解读 http://www.cnblogs.com/yourarebest/p/5423906.html Sch ...

  8. 【转】log4js在PM2的cluster模式下大坑

    请直接查看原文:https://blog.yourtion.com/fix-log4js-with-pm2-not-work.html 之前一直使用 debug 还有 console.log 去打日志 ...

  9. 解决Redis Cluster模式下的排序问题

    通常的redis排序我们可以这么做: 比如按商品价格排序:sort goods_id_set by p_*_price 这样在非集群模式下是没问题的,但如果在集群模式下,就会报错: 说是在集群模式下不 ...

随机推荐

  1. Linux下进程信息的深入分析

    这里我们主要介绍进程的状态,进程的状态可以通过/proc/PID/status来查看,也可以通过/proc/PID/stat来查看. 如果说到工具大家用的最多的ps也可以看到进程的信息.这里我们通过/ ...

  2. crm使用soap删除下拉框

    //C# 代码: //DeleteOptionSetRequest request = new DeleteOptionSetRequest(); //request.Name = "new ...

  3. Web安全漏洞及攻击

    背景介绍 先说一个在互联网上常见,但是普通人又不太理解的东西--“验证码”. 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell ...

  4. 添加 XML内Rows数据

    public static void addItemToXml(string method,string firstKey,string id,string checkName,string refV ...

  5. Linux Grub系统加密、破密、修复

    一.在重新启动系统时候按任意键进入 grub界面  Grub加密 一.title前的密码 修改grub.conf 这种加密只是在用户要进入grub界面的时候提示要输入密码,但是可以正常进入系统,有没有 ...

  6. Tcl学习之--列表|字典

    [列表|字典] Tcl使用列表来处理各种集合,比方一个目录中的全部文件,以及一个组件的全部选项.最简单的列表就是包括由随意个空格.制表符.换行符.分隔的随意多个元素的字符串.比方: JerryAlic ...

  7. Memory Analysis环境安装

    安装MAT(MAT在eclipse的页面:http://www.eclipse.org/mat/downloads.php) 显示饼图的时候,需要安装BIRT Chart Engine插件,通过Ins ...

  8. 零基础学python-5.1 数字简单介绍

    1.创建数值对象并赋值 a=1#整数 b=1.1#浮点数 c=1.23e5#实数 d=1.23+4.56j#虚数 2.更新数值对象 注意:由于数值对象是不可变,所以与其说更新,还不如说把变量名从一个对 ...

  9. 大话设计模式C++实现-第14章-观察者模式

    一.UML图 关键词:Subject维护一个Observer列表.Subject运行Notify()时就运行列表中的每一个Observer的Update(). 二.概念 观察者模式:定义了一种一对多的 ...

  10. Django框架之ORM

    1,字段和字段的参数 1.1>ORM的概念:对象映射模型(Objects Relational Model)是一种为了解决面向对象和关系型数据库存在的互不匹配的现象和技术,简单的说,ORM是通过 ...