学完spark一脸懵逼怎么办,基于spark最新版本3.0.0我们来探探spark底层运行原理,看完不懂的来捶我【狗头】

前言:

学习完spark之后,其实只是大致懂了怎么去用这个框架,但是对于它是怎么运行的还是一无所知,所以为了更加清楚的了解框架底层到底是怎么实现和运行的,我们需要跟踪源码看看它底层是怎么实现的

花费很多精力才追完源码,看完觉得有帮助的朋友三连哦,请不要下次一定😜

一 spark应用运行流程图示

在这里插入图片描述

步骤:

1 spark向yarn提交运行指令 bin/java ApplicationMaster

2 yarn会在某个NodeManager启动ApplicationMaster

3 AM启动Driver线程,执行用户类的main方法

4 AM向RM进行注册、申请资源

5 RM向AM返回可用资源,AM分配资源

6 AM根据资源访问NM,并启动Executor

​ 6.1 Executor启动后会注册通信,并收到消息

​ 6.2 收到消息后会执行通信对象的onStart方法

7 Executor向driver反向注册

8 Driver向Executor反馈消息,注册完毕

​ 8.1Executor接收消息之后,创建计算对象,等待任务的执行

9 Driver进行任务的划分并发送给Executor进行计算

二 spark应用运行流程源码分析

我们一般都是基于yarn cluster模式来进行部署,我们也就按照这个模式来进行追踪源码

之前在我们配好yarn模式之后,我们根据官方文档给的案例进行一次测试

bin/spark-submit
--class org.apache.spark.examples.SparkPi
--master yarn
--deploy-mode cluster
./examples/jars/spark-examples_2.11-2.1.1.jar 10

当时我们并不知道为什么要这样去写,我们去查看spark-submit脚本

exec "${SPARK_HOME}"/bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"

发现其实就是去调用org.apache.spark.deploy.SparkSubmit这个类

1 提交参数的封装

我们去查看SparkSubmit这个类的源码

def main(args: Array[String]): Unit = {
   
    val submit = new SparkSubmit()
    submit.doSubmit(args)
}

在main方法中创建了一个SparkSubmit对象,对象调用了doSubmit方法,传的参数就是我们写的那些参数

val appArgs = parseArguments(args) //解析参数

在doSubmit方法中,我们看到这个方法,看的出是一个解析参数的方法,我们再进去看看是怎么进行参数的解析的

protected def parseArguments(args: Array[String]): SparkSubmitArguments = {
   
    new SparkSubmitArguments(args)
}

我们进入到SparkSubmitArguments类中,发现有很多变量和方法用来封装参数,有一个handle方法,就是处理参数的方法了

    protected final String CLASS = "--class";
    protected final String CONF = "--conf";
    protected final String DEPLOY_MODE = "--deploy-mode";
    protected final String MASTER = "--master";
    protected final String NAME = "--name";



override protected def handle(opt: String, value: String): Boolean = {
   
    opt match {
   
      case NAME =>
        name = value

      case MASTER =>
        master = value

      case CLASS =>
        mainClass = value

      case DEPLOY_MODE =>
        if (value != "client" && value != "cluster") {
   
          error("--deploy-mode must be either \"client\" or \"cluster\"")
        }
        deployMode = value
//下面还有很多,我们就只看比较熟悉的几个

参数解析完成之后,我们回退到进入解析参数方法的那里

appArgs.action match {
   
      case SparkSubmitAction.SUBMIT => submit(appArgs, uninitLog)
      case SparkSubmitAction.KILL => kill(appArgs)
      case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs)
      case SparkSubmitAction.PRINT_VERSION => printVersion()
    }

我们可以知道这是模式匹配,并且只能匹配这几个值,但是我们不知道具体是哪个值,点进action里面看看

var action: SparkSubmitAction = null

action = Option(action).getOrElse(SUBMIT)

我们可以看到,如果action为空的时候,默认会给它一个值SUBMIT,此时我们知道是调用这行代码执行

case SparkSubmitAction.SUBMIT => submit(appArgs, uninitLog)

2 反射创建对象

进入submit方法之后,我们去掉一些暂时不关心的代码

private def submit(args: SparkSubmitArguments, uninitLog: Boolean): Unit = {
   

    def doRunMain(): Unit = {
   
      if (args.proxyUser != null) {
   
        val proxyUser = UserGroupInformation.createProxyUser(args.proxyUser,
          UserGroupInformation.getCurrentUser())
      } else {
   
        runMain(args, uninitLog)
      }
    }

我们可以发现,最后其实是调用runMain方法

//这是在准备提交的环境
val (childArgs, childClasspath, sparkConf, childMainClass) = prepareSubmitEnvironment(args)

//获取提交的类加载器
val loader = getSubmitClassLoader(sparkConf)

//将我们需要的jar包放到classPath下
for (jar <- childClasspath) {
   
    addJarToClasspath(jar, loader)
}

//通过类名加载类,获取类信息
mainClass = Utils.classForName(childMainClass)


val app: SparkApplication = if(classOf[SparkApplication].isAssignableFrom(mainClass)) {
   
    //通过反射创建对象并进行强转为SparkApplication类型
    mainClass.getConstructor().newInstance().asInstanceOf[SparkApplication]
} else {
   
    new JavaMainApplication(mainClass)
}


//启动app对象
app.start(childArgs.toArray, sparkConf)

通过上面的分析,我们知道会创建一个APP对象,但是我们还不知道具体是创建哪个类的对象,但是我们可以知道是通过prepareSubmitEnvironment方法获取的childMainClass

if 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值