在你面试的时候,可能你会说到整个流程,说到怎样确定driver、怎样初始化sc、触发job,到提交task,你可能很轻松的说出task是driver端通过层层封装,发给executor的,但是你如果不去看一下源码,可能你永远都不会知道这个有意思的地方——task运行的函数是通过广播方式发过去的
其实仔细看spark相关源码,可以在DAGScheduler
的submitMissingTasks
方法中发现如下代码:
private def submitMissingTasks(stage: Stage, jobId: Int) {
...
var taskBinary: Broadcast[Array[Byte]] = null
try {
var taskBinaryBytes: Array[Byte] = null
taskBinaryBytes = stage match {...}
taskBinary = sc.broadcast(taskBinaryBytes)
} catch {
...
}
val tasks: Seq[Task[_]] = new ShuffleMapTask(..., taskBinary)
taskScheduler.submitTasks(new TaskSet(
tasks.toArray,...))
}
我们可以看到,实际上提交的TaskSet
封装的并不是直接序列化后的task
,而是对应的广播