Spark Submit流程源码详解(on yarn)

Spark On YARN启动流程源码分析 1、spark-submit入口介绍 一般的spark作业都是通过命令行spark-submit相关的指令来进行提交,使用--master yarn来指定提交到对应的yarn集群上,如下: ./bin/spark-submit --class org.apache.spark.examples.SparkPi \ --master yarn \ --deploy-mode cluster \ --driver-memory 4g \ --executor-memory 阅读详情

Spark Submit流程(on yarn)

本文基于spark3.0.1

 #执行提交命令:
 bin/spark-submit --master yarn
 --deploy-mode cluster    
 --class com.Tencent.spark.WordCount 
 /opt/module/spark-standalone/bin/spark-1.0-SNAPSHOT.jar hdfs://hadoop:9820/input
 
 执行脚本实际是执行:
  bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"
 所以实际是在org.apache.spark.deploy.SparkSubmit类中开始执行

在这里插入图片描述

1.提交任务时,执行的是SparkSubmit类的mian方法 
2.main方法中:
val submit = new SparkSubmit() //创建SparkSubmit对象 -986行
submit.doSubmit(args) //利用submit对象执行提交动作 -1016行

3.调用父类的doSubmit方法:
  def doSubmit(args: Array[String]): Unit = {
	//解析参数
    val appArgs = parseArguments(args) //85行
  }

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

4.SparkSubmitArguments类内部定义了提交任务所需的参数,如master,deployMode等。还执行了解释方法:
  parse(args.asJava) //108行

5.parse()方法内部提供handle()方法,用来解析参数:
	//参数opt和value都是用户提交时指定的参数,如--master yarn
  override protected def handle(opt: String, value: String): Boolean = { //331
    opt match { 
      case NAME =>  //->--name
        name = value
      case MASTER => //->--master
        master = value
	...
    }
  }
6.参数解释完毕后:
      appArgs.action match { //89
      // 因为action = Option(action).getOrElse(SUBMIT),--SparkSubmitArguments类中227行
      case SparkSubmitAction.SUBMIT => submit(appArgs, uninitLog) //所以默认走的是这个,开始提交
      case SparkSubmitAction.KILL => kill(appArgs)
      case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs)
      case SparkSubmitAction.PRINT_VERSION => printVersion()
    }
7. submit方法中,执行runMain(args, uninitLog) //180
8. runmain方法中:
   //准备提交环境
  val (childArgs, childClasspath, sparkConf, childMainClass) = prepareSubmitEnvironment(args)//871
  
  mainClass = Utils.classForName(childMainClass) //通过类名获得类,使用反射
  //创建mainClass的实例,并将类型转换为SparkApplication, //912
  app: SparkApplication = mainClass.getConstructor().newInstance().asInstanceOf[SparkApplication] 
      
  				所以childMainClass到底是谁?
                       cluster模式:childMainClass = YARN_CLUSTER_SUBMIT_CLASS //715
                                   =org.apache.spark.deploy.yarn.YarnClusterApplication
                       client模式:childMainClass = args.mainClass  //就是我们提交的类 627
      
9. app.start() // 928 实际是YarnClusterApplication.start
      
"-------提交环境准备完成,Application开始运行--------"

10.在client类中:
private[spark] class YarnClusterApplication extends SparkApplication { //1575行
  override def start(args: Array[String], conf: SparkConf): Unit = {
    // SparkSubmit would use yarn cache to distribute files & jars in yarn mode,
    // so remove them from sparkConf here for yarn mode.
    conf.remove(JARS)
    conf.remove(FILES)

    new Client(new ClientArguments(args), conf, rpcEnv = null).run()
  }
}
    
11.Client类中有一个关键属性:创建yarn客户端对象
    val yarnClient = YarnClient.createYarnClient //72
12.创建对象后,执行run()方法

13. Client类的run方法中:
  def run(): Unit = { //1176
    this.appId = submitApplication() 
  }

14.submitApplication中:
//Submit an application running our ApplicationMaster to the ResourceManager.
def submitApplication(): ApplicationId = { //165
    var appId: ApplicationId = null
    try {
      launcherBackend.connect()
      //根据hadoopconf初始化客户端
      yarnClient.init(hadoopConf)
      //yarn客户端启动
      yarnClient.start()

      // Get a new application from our RM
      val newApp = yarnClient.createApplication()
      val newAppResponse = newApp.getNewApplicationResponse()
      //获取应用的id,在yarn应用程序中,每一个应用都是有唯一的应用id
      appId = newAppResponse.getApplicationId()

      // Set up the appropriate contexts to launch our AM
      //内部是启动用于Appmaster的container和配置JVM的启动参数以及运行指令:启动AppMaster的命令
【集群模式】command = bin/java org.apache.spark.deploy.yarn.ApplicationMaster //拼接的指令,980行
【client模式】command = bin/java org.apache.spark.deploy.yarn.ExecutorLauncher
      val containerContext = createContainerLaunchContext(newAppResponse)  //196
      val appContext = createApplicationSubmissionContext(newApp, containerContext)

      // Finally, submit and monitor the application,提交的是运行指令及相关资源,jar包,路径等
      yarnClient.submitApplication(appContext)
  }
}

"-----------以上是申请启动AppMaster------------"

在org.apache.spark.deploy.yarn.ApplicationMaster类中:
1. val amArgs = new ApplicationMasterArguments(args) //获取AM需要的参数 842
2. master = new ApplicationMaster(amArgs, sparkConf, yarnConf) //创建ApplicationMaster 859
3. override def run(): Unit = System.exit(master.run()) // ApplicationMaster运行  890  

4. run()方法中:
	if (isClusterMode) {  //264
	        runDriver()
	      }

5. runDriver()中, //启动用户定义的程序,说明Driver就是用户定义的程序
     userClassThread = startUserApplication()  // 492

6. startUserApplication()方法中, 获取用户定义的main方法   
	val mainMethod = userClassLoader.loadClass(args.userClass) //718
      .getMethod("main", classOf[Array[String]])

7. 新起一个线程,运行用户定义的main方法
	val userThread = new Thread {
      override def run(): Unit = {
            mainMethod.invoke(null, userArgs.toArray)
      }
    }

8.  userThread.setName("Driver")//新起的线程命名为Driver,说明了Driver是以一个线程的形式运行在AppMaster
    userThread.start() //启动线程,因为线程运行的是用户定义的main方法,所以会进行SparkContext初始化

"------插入SparkContext初始化部分内容---------"
SparkContext进行初始化taskScheduler时,会执行下面的程序:
val backend = cm.createSchedulerBackend(sc, masterUrl, scheduler) //SparkContext类中2928行
createSchedulerBackend是一个抽象方法,其实现方法:
  //YarnClusterManager类下
  override def createSchedulerBackend(...)
      case "cluster" =>
        new YarnClusterSchedulerBackend(scheduler.asInstanceOf[TaskSchedulerImpl], sc) //45
  }
 new了一个YarnClusterSchedulerBackend,而YarnClusterSchedulerBackend是继承了YarnSchedulerBackend,
YarnSchedulerBackend类又继承了CoarseGrainedSchedulerBackend类,在CoarseGrainedSchedulerBackend的构造器中有一个属性:
val driverEndpoint = rpcEnv.setupEndpoint(ENDPOINT_NAME, createDriverEndpoint()) //435
说明在执行val backend = cm.createSchedulerBackend时,会执行YarnClusterSchedulerBackend父类的父类的构造器,继而创建了DriverEndpoint。也就是说,"在进行SparkContext初始化时,DriverEndpoint就被创建了"。

"-------------插播完成,下面继续------------- "


9.  阻塞当前线程,等待Driver创建好SparkContext,返回结果 
    val sc: SparkContext = ThreadUtils.awaitResult //499

10. val rpcEnv = sc.env.rpcEnv //通过SparkContext获取通讯环境,说明通讯环境就在SparkContext中。

11. 通过yarnRMClient向RM注册AM
	registerAM(host, port, userConf, sc.ui.map(_.webUrl), appAttemptId) // 507

12. 获取Driver的EndpointRef。注:在创建SparkContext时,就已经创建了Driver的Endpoint
    val driverRef = rpcEnv.setupEndpointRef //509 

13. 关键代码: 
createAllocator(driverRef, userConf, rpcEnv, appAttemptId, distCacheConf) //512
createAllocator()方法中:通过YarnRMClient创建资源获取器
	allocator: YarnAllocator = client.createAllocator //465
	allocator是YarnAllocator的实例,而YarnAllocator是负责从RM申请containers,并决定container的用途。来	 源于YarnAllocator类的源码注释。

14. 拿allocator申请资源
	allocator.allocateResources() //479
	allocateResources()方法中:
	def allocateResources(): Unit = synchronized {
	    val allocateResponse = amClient.allocate(progressIndicator)
	    //申请可分配的资源
	    val allocatedContainers = allocateResponse.getAllocatedContainers()
		//如果申请到了, 就决定这个Container的用途
	    if (allocatedContainers.size > 0) {
	      handleAllocatedContainers(allocatedContainers.asScala)
	    }
    }
	handleAllocatedContainers()方法中,会确定Container的用途
	runAllocatedContainers(containersToUse) //481
      
	runAllocatedContainers方法中:
	//对于每个container
    for (container <- containersToUse) 
        //判断当前运行的Executor数量是否小于目标数量,注:Executor是运行在container中
        if (runningExecutors.size() < targetNumExecutors) )
            //如果小于,判断是否需要运行Containers
        	if (launchContainers) 
                //需要的话就起新线程运行Executor
        	  launcherPool.execute(() => {
        	    try {
        	      new ExecutorRunnable().run() //571
                }
              }
                                   )

           执行run()方法:
        def run(): Unit = {
 		   logDebug("Starting Executor Container")
 		   nmClient = NMClient.createNMClient() //创建和NM通信的客户端
 		   nmClient.init(conf)
 		   nmClient.start()
 		   startContainer() //Container是在NM中运行的,正式启动NM上的Container
        }
		startContainer()中:
		val commands = prepareCommand() //101行,准备在Container上运行的Java命令
		prepareCommand()中:拼接命令:
		//这是在container上运行的后台进程
		commands=/bin/java/org.apache.spark.executor.YarnCoarseGrainedExecutorBackend // 207

//目前为止:AppMaster进程中,有Driver线程,DriverEndpoint,YarnRMClient,NMclient
"总结:以上是启动AppMaster后再在AppMaster中起新线程启动Driver,然后申请Container的资源,然后启动Container,在Container上运行org.apache.spark.executor.YarnCoarseGrainedExecutorBackend后台进程"

 在org.apache.spark.executor.YarnCoarseGrainedExecutorBackend后台进程中
1.createFn :CoarseGrainedExecutorBackend = new YarnCoarseGrainedExecutorBackend //75 

//这个CoarseGrainedExecutorBackend并不是上面的CoarseGrainedExecutorBackend,这个是它的伴生对象
2.CoarseGrainedExecutorBackend.run(backendArgs, createFn) //81

3.run方法中:
val fetcher: RpcEnv = RpcEnv.create() //create()是用来获取NettyRpcEnv,是一个简单的环境   289
 
4.获取到通讯环境后,利用driverUrl获得Driver的EndpointRef
var driver: RpcEndpointRef = null
driver = fetcher.setupEndpointRefByURI(arguments.driverUrl) //303

5.根据Driver的EndpointRef向Driver发请求,请求SparkApp的配置
val cfg = driver.askSync[SparkAppConfig](RetrieveSparkAppConfig(arguments.resourceProfileId)) //311

6.利用获得的SparkAppConfig,重新创建通讯环境。
val driverConf = new SparkConf()
val env = SparkEnv.createExecutorEnv(driverConf, ...) //331
                                   
7.向通讯环境注册一个名称为Executor的通讯端点,是一个CoarseGrainedExecutorBackend对象。注意,这个不是用于计算任务的Executor,是用来通讯的Endpoint
env.rpcEnv.setupEndpoint("Executor", ...)) //334

8.'在注册端点后,Dispatcher会向端点的InbOx放入一个Onstart()方法,进行Endpoint的初始化
 
9.env.rpcEnv.awaitTermination() //阻塞当前线程,直到Onstart()结束
    
"总结:YarnCoarseGrainedExecutorBackend是另一个NOdeManager上在container上的一个后台进程,类似于AppMaster,运行Task的executor对象运行在这个进程中。而CoarseGrainedExecutorBackend是进程中的一个Endpoint,名称为Executor,负责和Driver进行通讯"

CoarseGrainedExecutorBackend.Onstart()

1. 可以看出,这个Onstart()作用就是连接driver进行一系列操作
	logInfo("Connecting to driver: " + driverUrl) //83

2. driver = Some(ref) //获取Driver的EnpointRef  92

3. 获取到Driver的EnpointRef后,CoarseGrainedExecutorBackend(名字叫做Executor)向Driver发送			RegisterExecutor的消息,要求回复True or false。这就是反向注册。
	ref.ask[Boolean](RegisterExecutor())  //93

"------下面是Driver收到RegisterExecutor消息后,如何处理-----"
Driver线程是以DriverEndpoint作为通讯端点
消息发送和接收的对应方法:
send --> receive
ask --> receiveAndReply
而上面ref.ask[Boolean](RegisterExecutor())是需要返回值的,所以会调用receiveAndReply方法

4. DriverEndpoint类中的receiveAndReply()中
   //执行消息判断
   case RegisterExecutor(...) =>  //207
	//如果executorDataMap中已经有了这个executorId的ID,就报ID已存在的异常
     if (executorDataMap.contains(executorId)) {
       context.sendFailure(new IllegalStateException(s"Duplicate executor ID: $executorId"))
       //如果executorId, hostname在黑名单,就报Executor is blacklisted异常
     } else if (scheduler.nodeBlacklist.contains(hostname) ||
         isBlacklisted(executorId, hostname)) {
        context.sendFailure(new IllegalStateException(s"Executor is blacklisted: $executorId"))
     } else {
         //回复true
         context.reply(true)  //255
     }

"CoarseGrainedExecutorBackend收到Driver的回复后如何处理"

5. CoarseGrainedExecutorBackend的start()方法中
   case Success(_) =>  //96
        self.send(RegisteredExecutor) //如果Driver回复true,自己给自己发送一个RegisteredExecutor消息
   case Failure(e) =>  //失败,退出Executor
        exitExecutor(1, s"Cannot register with driver: $driverUrl", e, notifyDriver = false)

6. 自己给自己发送RegisteredExecutor,需要在receive()方法中处理:                        
  override def receive: PartialFunction[Any, Unit] = {  //147
    case RegisteredExecutor =>
      logInfo("Successfully registered with driver") 
        //创建一个executor对象,这个才是我们经常说用于计算运行Task的executor
        executor = new Executor(executorId, hostname, env, userClassPath, isLocal = false,
          resources = _resources)
      	//然后向Driver发送LaunchedExecutor(executorId)消息,已经创建executor
        driver.get.send(LaunchedExecutor(executorId))
  }
                        
7. DriverEndpoint需要在receive()中处理LaunchedExecutor(executorId))消息
      case LaunchedExecutor(executorId) =>  //198
        executorDataMap.get(executorId).foreach { data =>
          data.freeCores = data.totalCores
        }
        makeOffers(executorId)  //给executor发offer,意味着executor可以运行Task了
      
                      
                                   

Yarn源码剖析(二) --- spark-submit spark-submit 前言 上文Yarn源码剖析(一) --- RM与NM服务启动以及心跳通信介绍了yarn是如何启动的,本文将介绍在yarn正常启动后,任务是如何通过spark-submit提交到yarn上的。 spark-submit脚本 1. 先来观察一下任务提交时的spark-submit脚本中各个参数的含义(并没列举所有,只列举了关键的几个参数) /spark/bin/s... 阅读详情

相关推荐

Spark源码学习(9)——Spark On Yarn

本文要解决的问题:了解Spark在Yarn平台上的运行过程。修改配置文件首先需要修改配置文件spark-env.sh。在这个文件中需要添加两个属性:Export HADOOP_HOME=/../hadoop..ExportHADOOP_CONF_DIR=/../hadoop/etc/hadoop这里,一个是要hadoop的home目录。一个是配置文件目录。还需要配置一个就是spark-default

Miracle_shen的博客 1366

Spark on yarn——Spark提交任务到yarn集群源码分析

1. 当使用spark-submit命令提交任务时,处理类是SparkSubmit,核心代码如下: object SparkSubmit extends CommandLineUtils with Logging { override def main(args: Array[String]): Unit = { appArgs.action match { case ...

u012361112的博客 2123

【源码分析】Spark on Yarn应用提交流程

本文直接从SparkSubmit说起,脚本提交过程在之前的《spark-submit脚本执行过程》文章中已经说明。 一、主要过程概括 1、执行org.apache.spark.deploy.SparkSubmit的main方法提交。 2、运行yarn客户端的run方法。 3、向ResourceManager提交application请求container用来运行ApplicationMaster...

初心江湖路的博客 524

Spark on Yarn用执行流程图解(包含stage流程)

@Author : Spinach | GHB @Link : http://blog.youkuaiyun.com/bocai8058 文章目录前言 前言

GSpinach的博客 7227

Spark源码解析之org.apache.spark.deploy.SparkSubmit源码解析

前面解读launch.main的时候已经了解了spark-submit的提交流程,这里大概看下流程。 当打jar提交到集群运行的时候,一般会设置一些参数,例如本地提交examples的SparkPi: spark-submit \ --class org.apache.spark.examples.SparkPi \ --master spark://192.168.2.1:7077 \ D...

攸的博客 1252

CCS软件仿真插件移植避坑指南:从CCS5.5到7.4的完整流程

本文详细介绍了将CCS软件仿真插件从CCS5.5迁移至CCS7.4的完整流程与避坑指南。针对TMS320F28335等C2000系列芯片,重点解析了仿真核心文件、配置数据库、连接定义及驱动文件的移植步骤,并通过两个实战Demo验证了移植后仿真环境的可用性,帮助开发者在无硬件条件下继续高效进行算法验证与调试。

defi6farmer的博客 456

Spark on Yarn 提交流程源码解析

源码版本:spark-3.1.2 spark提交命令 bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn ./examples/jars/spark-examples_2.12-3.1.2.jar 10 进入到spark-submit 可以程序入口类SparkSubmit if [ -z "${SPARK_HOME}" ]; then source "$(dirname "$0")"/..

qq_24186017的博客 999

实验六 存储器实验

只读存储器(ROM)是一种在正常工作时其存储的数据固定不变,其中的数据只能读出,不能写入,即使断电也能够保留数据,要想在只读存储器中存入或改变数据,必须具备特定的条件。当地址为00000101时,会分别在数据位宽为8,16,32的只读寄存器中找到地址为00000101所对应的十进制地址位置,也就是地址为5的数据,并将其分别以8位,16位,32位输出。因此,输出保持为0。因此,当异步清零信号为1时,无论其他输入信号是什么,触发器的输出都会被强制清零,输出为0。1)寄存器输入0011,使能端1,异步清零0。

wenmou1111的博客 3001

Spark源码之Spark on Yarn运行时架构

在当今大数据时代,数据处理和分析已成为各行各业的核心任务之一。为了有效地处理海量数据并实现高性能的分布式计算,Apache Spark作为一款强大而灵活的开源框架崭露头角。Spark的成功不仅源于其卓越的性能和易用性,更在于其开放源代码的本质,为研究者、工程师和开发者提供了深入学习的机会。Spark源码的学习可谓是解锁这一分布式计算框架内在奥秘的关键之一。理解Spark的底层实现细节,深入研究其核心组件和算法,不仅有助于更好地利用Spark提供的丰富功能,还能为解决实际业务问题提供定制化的解决方案。

道可道非常道 1274

告别第三方应用!用Android原生API搭建Miracast投屏接收器

本文深入探讨如何利用Android原生API开发Miracast接收器,绕过第三方依赖,实现高效的屏幕共享。通过Wi-Fi P2P直连、反射调用隐藏API和RTSP会话协商等核心技术,为开发者提供了一套完整的Miracast接收端解决方案,适用于多屏协同场景。

weixin_29174141的博客 389

一文介绍Linux EAS

EAS只在系统负载不重时,即系统中每个CPU的利用率都低于其算力的80%时才被启用,而且选出的最节能CPU只有比线程当前运行的CPU节约能量大于6%时,线程才会迁移到该CPU运行。因此EAS为线程选择最节约能量的CPU来运行的前提条件是很苛刻的,针对重载场景(比如游戏),EAS的功能应该很少被使用起来,针对重载场景的功耗优化,这里可能是一个值得尝试的点。算力(capacity)是CPU调度中的一个基础概念,它反映的是一个CPU的计算能力,是个规格化的值,可以通过读取Android手机的文件节点。

youzhangjing_的博客 1234

Spark内核之YARN Cluster模式源码详解(Submit详解)

目录 一、YARN Cluster模式图解 二、Yarn cluster运行机制源码分析 1.SparkSubmit 2. yarn.YarnClusterApplication 3. ApplicationMaster 4. 注册ApplicationMaster并申请资源启动ExecutorBackend 5. CoarseGrainedExecutorBackend 6. Spark通用运行流程概述 由于在实际工厂环境下使用的绝大多数的集群管理器是Hadoop YARN,...

Markble 7896

任务混部最少服务器数量计算问题

这里的并行度指的是该任务运行时会占用的服务器数量。要注意的是,一个服务器在每个时刻可以被任意任务使用,但同一时刻最多只能被一个任务占用,并且任务运行结束后会立即释放服务器(结束时刻不占用)。最后,我们从字典中找出服务器数量的最大值,这个最大值就是完成这批任务混部最少需要的服务器数量。对于每个任务,我们会遍历其对应的时间区间,将该任务的并行度累加到对应时刻的服务器数量上。任务混部的目标是让这批任务由同一批服务器承载运行,你需要计算完成这批任务混部最少需要多少服务器,以此来最大化控制资源成本。

m0_62153576的博客 106

Spark源码——Spark on YARN SparkSubmit初始化、ApplicationMaster的启动注册

文章目录流程图 我们知道,在YARN资源管理上提交Spark应用程序之后,首先会执行以下步骤: 第一步,启动ApplicationMaster 第二步,ApplicationMaster启动之后,向ResourceManager申请资源(也就是需要的Container) 第三步,在申请的Container中启动真正执行Task的Executor 流程图 ...

aof 704

华为OD机试双机位C卷-简单的解压缩算法(C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【简单的解压缩算法】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD真题【简单的解压缩算法】。

qq_45776114的博客 474

AutoSAR配置与实践(实践篇)11.1 如何通过IPDU分组控制报文收发

注意这个新增的action其实是一个用户回调函数,在函数中进行配置字的判断,即可完成用户条件的判断(TRUE/FALSE),注意用户条件是用户封装的函数,用于输入给后续的逻辑判断和rule。进行PDU的拆分后,根据配置字可以选择PDU是否使能了。PDU组拆分后可分为常规PDU组和可配PDU组(新增),诊断一方面按原有逻辑控制常规PDU组,另一方面控制新的可配PDU组。举例说明,诊断场景:使能,配置字满足,则用户条件为TURE,表示期望使能可配PDU组(诊断禁止服务场景类似方式,在此不再列举)。

nihaoljq2010的博客 833

Spark-Submit提交流程源码分析(Yarn-Cluster源码分析, Yarn-Cluster 和 Yarn-Client 的区别)

目录 概念简介 Hadoop Yarn组件介绍: ResourceManager(RM) NodeManager(NM) ApplicationMaster(AM) Container Yarn-Cluster模式 Spark On Yarn 一、 SparkSubmit 分析 二、转到 Client 三、ApplicationMaster 四、Coarse...

康师傅没有眼泪 1632

关于DEJA_VU3D - Cesium功能集专栏说明

专栏主要目的是对工作中基于Cesium实现过的功能进行整合,暂时打算一周2-3更的样子来更新,每一篇都会奉上完整源代码(尽可能把代码简洁一些)。功能实现大多数是自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小130个左右的功能,后续也会不断的更新。..........................................

总得学点什么的博客 2万+

spark on yarn 作业提交流程源码

借图。

weixin_43839095的博客 703

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Spark(四十九):Spark On YARN启动流程源码分析(一)

引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析。 spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 # Run on a Spark standalone cluster ./bin/spark-submit \ --class org.apache.spark.example...

weixin_30852367的博客 936

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Spark on Yarn分析

Spark on yarn

zhangkai1992的专栏 888

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Spark Yarn Cluster 模式启动流程源码分析

spark-submit.s 首先由spark-submit.sh脚本提交任务: if [ -z "${SPARK_HOME}" ]; then source "$(dirname "$0")"/find-spark-home fi # disable randomized hash for string in Python 3.3+ export PYTHONHASHSEED=0 exec "${SPARK_HOME}"/bin/spark-class org.apache.spark.de

RJ_Dream的博客 754

Spark on YARN的任务提交流程源码分析一:cluster模式

Spark的部署模式有Standalone、Hadoop YARN、Apache Mesos、Kubernete四种。 在我们平时的练习中,可能会用到Standalone模式,但是在实际生产环境中,绝大多数用的还是YARN(Mesos国内基本很少用)。而对于YARN的两种模式,个人认为cluster模式比较多,所以,我们先从cluster模式讲起。 之前我也知道在一个Spark程序中,Driver是什么,Executor是什么,在YARN的cluster模式下,Driver是运行在Applicati.

yxf19034516的博客 730

spark-yarn 任务提交详解

Spark支持3种集群管理器(Cluster Manager) 分别为: Standalone:独立模式,Spark 原生的简单集群管理器,自带完整的服务,可单独部署到一个集群中,无需依赖任何其他资源管理系统,使用 Standalone 可以很方便地搭建一个集群; Hadoop YARN:统一的资源管理机制,在上面可以运行多套计算框架,如 MR、Storm等。根据 Driver 在集群中的位置不同,分为 yarn client 和 yarn cluster; Apache Mesos:一个强大的分布

z7one 845

Spark On YARN启动流程源码分析(一)

参考原文地址:https://www.cnblogs.com/yy3b2007com/p/10934090.html 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析。 spark源码对应的spark版本为2.12 一、spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 # Run on a Spark standalone cluster ./bin/spark-submit \ --class or

道语星航 477

不再踩坑!Spark on YARN 资源本地化:原理、配置与生产环境最佳实践!

我们知道Spark on YARN模式下,不需要在YARN集群上的每一个NodeManager上都部署Spark及其他依赖文件,只需要在Spark作业提交的客户端所在的物理机上有一套完整的Spark环境即可,但是Spark在运行的时候是需要这些依赖文件的,那么Spark on YARN究竟是怎么做到的呢?

涤生大数据 1313
上一篇: Hive中 Order by,Sort by, Distribute by, Cluster by详解
下一篇: Spark Job提交的整体流程源码详解
dab-hand
博客等级 码龄7年 10粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值