spark task启动

原创 2015年11月19日 14:39:31
    woker接受到LaunchTask消息后会启动task,以local模式为例,代码如下。task是由executor来启动的
override def receiveWithLogging = {
  case ReviveOffers =>
    reviveOffers()
    ......

def reviveOffers() {
  val offers = Seq(new WorkerOffer(localExecutorId, localExecutorHostname, freeCores))
  val tasks = scheduler.resourceOffers(offers).flatten
  //把task循环启动起来
  for (task <- tasks) {
    freeCores -= scheduler.CPUS_PER_TASK
    executor.launchTask(executorBackend, taskId = task.taskId, attemptNumber = task.attemptNumber,
      task.name, task.serializedTask)
  }
  if (tasks.isEmpty && scheduler.activeTaskSets.nonEmpty) {
    // Try to reviveOffer after 1 second, because scheduler may wait for locality timeout
    context.system.scheduler.scheduleOnce(1000 millis, self, ReviveOffers)
  }
}

launchTask会将task封装为TaskRunner,放入线程池中运行,此时task是被序列化的
def launchTask(
    context: ExecutorBackend,
    taskId: Long,
    attemptNumber: Int,
    taskName: String,
    serializedTask: ByteBuffer) {
  val tr = new TaskRunner(context, taskId = taskId, attemptNumber = attemptNumber, taskName,
    serializedTask)
  runningTasks.put(taskId, tr)
  threadPool.execute(tr)
}
TaskRunner是一个实现Runnable的线程执行体,被放入线程池后续先进性反序列化,然后执行该task,汇报task状态为running
override def run() {
    val deserializeStartTime = System.currentTimeMillis()
    Thread.currentThread.setContextClassLoader(replClassLoader)
    val ser = env.closureSerializer.newInstance()
    logInfo(s"Running $taskName (TID $taskId)")
    execBackend.statusUpdate(taskId, TaskState.RUNNING, EMPTY_BYTE_BUFFER)
    var taskStart: Long = 0
    startGCTime = gcTime


    try {
    	//反序列化
      val (taskFiles, taskJars, taskBytes) = Task.deserializeWithDependencies(serializedTask)
      updateDependencies(taskFiles, taskJars)
      task = ser.deserialize[Task[Any]](taskBytes, Thread.currentThread.getContextClassLoader)


      // If this task has been killed before we deserialized it, let's quit now. Otherwise,
      // continue executing the task.
      if (killed) {
        // Throw an exception rather than returning, because returning within a try{} block
        // causes a NonLocalReturnControl exception to be thrown. The NonLocalReturnControl
        // exception will be caught by the catch block, leading to an incorrect ExceptionFailure
        // for the task.
        throw new TaskKilledException
      }


      attemptedTask = Some(task)
      logDebug("Task " + taskId + "'s epoch is " + task.epoch)
      env.mapOutputTracker.updateEpoch(task.epoch)


      // 开始执行task
      taskStart = System.currentTimeMillis()
      val value = task.run(taskAttemptId = taskId, attemptNumber = attemptNumber)
      val taskFinish = System.currentTimeMillis()


      // If the task has been killed, let's fail it.
      if (task.killed) {
        throw new TaskKilledException
      }
      ......
      val directResult = new DirectTaskResult(valueBytes, accumUpdates, task.metrics.orNull)
      val serializedDirectResult = ser.serialize(directResult)
      val resultSize = serializedDirectResult.limit


      // directSend = sending directly back to the driver
      val serializedResult = {
        if (maxResultSize > 0 && resultSize > maxResultSize) {
          logWarning(s"Finished $taskName (TID $taskId). Result is larger than maxResultSize " +
            s"(${Utils.bytesToString(resultSize)} > ${Utils.bytesToString(maxResultSize)}), " +
            s"dropping it.")
          ser.serialize(new IndirectTaskResult[Any](TaskResultBlockId(taskId), resultSize))
        } else if (resultSize >= akkaFrameSize - AkkaUtils.reservedSizeBytes) {
          val blockId = TaskResultBlockId(taskId)
          env.blockManager.putBytes(
            blockId, serializedDirectResult, StorageLevel.MEMORY_AND_DISK_SER)
          logInfo(
            s"Finished $taskName (TID $taskId). $resultSize bytes result sent via BlockManager)")
          ser.serialize(new IndirectTaskResult[Any](blockId, resultSize))
        } else {
          logInfo(s"Finished $taskName (TID $taskId). $resultSize bytes result sent to driver")
          serializedDirectResult
        }
      }
      execBackend.statusUpdate(taskId, TaskState.FINISHED, serializedResult)
    } catch {
      .....
    } finally {
      // Release memory used by this thread for shuffles
      env.shuffleMemoryManager.releaseMemoryForThisThread()
      // Release memory used by this thread for unrolling blocks
      env.blockManager.memoryStore.releaseUnrollMemoryForThisThread()
      // Release memory used by this thread for accumulators
      Accumulators.clear()
      runningTasks.remove(taskId)
    }
  }
}  
  


大数据:Spark Core(二)Driver上的Task的生成、分配、调度

1. 什么是Task? 在前面的章节里描述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Work...
  • raintungli
  • raintungli
  • 2017年04月14日 09:21
  • 4450

Spark reduce task数目设置,解决小任务过多slave挂掉

spark.default.parallelism=8
  • lovebyz
  • lovebyz
  • 2016年09月08日 17:29
  • 2413

Spark job 的执行流程简介

Spark 应用程序在提交执行后,控制台会打印很多日志信息,这些信息看起来是杂乱无章的,但是却在一定程度上体现了一个被提交的 Spark job 在集群中是如何被调度执行的,这里将会向大家介绍一个典型...
  • haohaixingyun
  • haohaixingyun
  • 2016年10月10日 12:39
  • 308

Spark Task执行原理

Task执行原理流程: 1.当Driver中SchedulerBackend给ExecutorBackend发送launchTask之后,首先会反序列化TaskDescription。 2.Exe...
  • u013063153
  • u013063153
  • 2017年01月16日 12:22
  • 612

spark中tasks数量的设置

spark中有partition的概念,每个partition都会对应一个task,task越多,在处理大规模数据的时候,就会越有效率。不过task并不是越多越好,如果平时测试,或者数据量没有那么大,...
  • mask1188
  • mask1188
  • 2016年07月24日 14:21
  • 4014

Spark的stage & job & task 到底是什么 ,以及划分原理

这几个概念很容易混淆,需要写一遍文章梳理 Spark的stage & job & task 到底是什么 ,以及划分原理...
  • haohaixingyun
  • haohaixingyun
  • 2016年10月16日 20:35
  • 3885

网络原因造成 spark task 卡住

主机名映射出错背景:Yarn集群新加入了一批Spark机器后发现运行Spark任务时,一些task会无限卡住且driver端没有任何提示。解决:进入task卡住的节点查看container stder...
  • lsshlsw
  • lsshlsw
  • 2017年05月10日 00:36
  • 1117

Spark task not serializable错误的分析和处理

在编写代码Spark应用时出现以上的问题,最后发现是因为Dataset的foreach方法中传入的参数ForeachFunction引起的,代码如下: projectDataSourceDFF...
  • achilles12345
  • achilles12345
  • 2017年09月01日 22:05
  • 812

Spark入门之七:了解SparkSQL运行计划及调优

优化过程中常用到方法 查看查询的整个运行计划  scala>query.queryExecution 查看查询的Unresolved LogicalPlan  scala>query.que...
  • sun7545526
  • sun7545526
  • 2015年11月07日 21:10
  • 3318

Spark源码分析之六:Task调度(二)

话说在《Spark源码分析之五:Task调度(一)》一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法。这个方法针对接收到的ReviveOffers事件进行处...
  • lipeng_bigdata
  • lipeng_bigdata
  • 2016年02月22日 16:33
  • 3245
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:spark task启动
举报原因:
原因补充:

(最多只允许输入30个字)