작업 실행 원칙 스파크 (V) - 작업을 수행

        원리 스파크 메시징 ((3 개) https://www.cnblogs.com/SysoCjs/p/11355900.html 제 기준점 (6)를 통해, 실행자 작업은 컨테이너에 의해 수행 된 후), 실행 프로그램은 메시지를 수신 LaunchTask 작업을 수행한다 (GoraseGrainedExecutorBackend LaunchTask가 DriverEndpoint로부터 메시지를 수신 한 후, 실제로, 실행 프로그램의 launchTasks 메소드를 호출한다). 작업이 TaskRunner 프로세스를 만들 때, thredPool, 집행자에 의해 통일 파견했습니다.

        TaskRunner는 실행 방법, 주요 작업하는 방법이 있습니다 작업 자체 (ShuffleMapTask 및 ResultTask)을 통해 전송하기를, 그리고 시퀀스 실행 방지 작업에 작업 개체에 다음 jar 파일 및 다른 항 순서에 의존하고, 방법. 작업은 추상 클래스이기 때문에, 두 가지 특정 서브 클래스와 ShuffleMapTask ResultTask을 달성했다.

방법 TaskRunner.run 소스 부분 :

RUN DEF 오버라이드 () : 단위 = {
     // 생성하는 메모리 관리 인스턴스 --taskMemoryManager, 임무 중에 메모리 관리 작업 
    발 taskMemoryManager = 새로운 새로운 TaskMemoryManager (env.memoryManager, taskld) 
    발 deserializeStartTime = System.currentTimeMillis는 () 
 
    는 Thread.currentThread .setContextClassLoader (replClassLoader) 
    발 빼앗아 = env.closureSerializer.newInastance () 
 
    // 작업에 전송 시작 메시지는 드라이버 터미널, 드라이버에 상태 업데이트 알림 실행 
    execBackend.statusUpdate (taskld, TaskState.RUNNING, EMPTY_BYTE_BUFFER) 
    긴 : var에 TaskStart = 0 
    startGCTime = computeTotalGcTime () 
 
    은 try {
         //등 작업 파일, 항아리, 코드를 실행하는 것이 필요는 직렬화 
        발 (taskFiles, taskJars, taskBytes) = Task.deserializeWithDependencies (serializedTask) 
        updateDependencies (taskFiles, taskJars) 
        작업 = ser.deserialize [작업 [있는 Any] (taskBytes을 , Thread.currentThread.getContextClassLoader) 
        task.setTaskMemoryManager (taskMemoryManager는) 
 
        // 작업이 직렬화 죽이기 전에 꺼져있는 경우에는 예외가 발생합니다 
        경우 (사망) {
             던져  새로운 새로운 TaskKilledException 
        } 
 
        env.mapOutputTracker.updateEpoch (task.epoch) 
 
        // 작업 runTask 메서드 호출, 작업은 추상 클래스, 그래서 그 서브 클래스의 구체적인 구현 --ShuffleMapTask 및 ResultTask 때문에 
        TaskStart = System.currentTimeMillis는 () 
        var에 threwException= 진정한 
        발 값 = 시도 { 
            발 고해상도 = task.run ( 
                taskAttemptId = TASKID, 
                attemptNumber = attemptNumber, 
                metricsSystem = env.metricsSystem) 
            고해상도 
        } 마지막으로 {...} 
        ... 
    } 
}

        다른 작업 엔티티 클래스, 그들은 계산에 대한 접근 방식의 차이의 결과가 될 것입니다.

        ShuffleMapTask 들어, 결과 BlockManager에 기록되며, 결국 ShuffleMapTask의 관리에 관련된 정보를 저장하는 MapStatus 객체가 이러한 결과는 정보 자체를 기억하지되는 DAGScheduler로 복귀하지만, 관련 접촉 BlockManager에 연산 결과 정보가 작업의 다음 단계는 얻을 필요가있을 것입니다 저장하는 입력 데이터를 기반으로. 소스 코드의 ShuffleMapTask.runTask 부분 :

override def runTask(context: TaskContext):MapStatus = {
    val deserializeStartTime = System.currentTimeMills()
    //反序列化获取RDD和RDD的依赖
    val ser = SparkEnv.get.closureSerializer.newInastance()
 
    val (rdd, dep) = ser.derialize[(RDD[_], ShuffleDependency[_, _, _])](
        ByteBuffer.wrap(taskBinary.value), Thread.currentThread.getContextClassLoader)
    _executorDeserializeTime = System.currentTimeMillis() - deserializeStartTime
 
    metrics = Some(context.taskMetrics)
    var writer:ShuffleWriter[Any, Any] = null
 
    try{
        val manager = SparkEnv.get.ShuffleManager
        writer = manager.getWriter[Any, Any](dep.shuffleHandle, partitionId, context)
        //首先调用rdd.iterator,如果RDD已经Cache或者Checkpoint,则直接读取结果;否则计算。
        writer.write(rdd.iterator(partition,context).asInstanceOf[Iterator[_<:Product2[Any, Any]]])
        //关闭writer,返回结果,包含数据的location和size等元数据信息
        writer.stop(success = true).get
    }catch{...}
}

        对于ResultTask,它的计算结果以func函数的形式返回。ResultTask.runTask部分源码:

override def runTask(context:TaskContext):U = {
    //反序列化广播变量,得到RDD
    val deserializeStartTime = System.currentTimeMillis()
    val ser = SparkEnv.get.closureSerializer.newInstance()
    val (rdd, func) = ser.deserialize[(RDD[T]. (TaskContext, Iterator[T]) => U)](
        ByteBuffer.wrap(taskBinary.value), Thread.currentThread.getContextClassLoader)
    _executorDeserializeTime = System.currentTimeMillis() - deserialiZeStartTime
    
    metrics = Some(context.taskMetrics)
    //返回
    func(context, rdd.iterator(partition, context))
}

 

추천

출처www.cnblogs.com/SysoCjs/p/11357054.html