目录
Task状态
Task 异常
Task状态与异常
Task状态
TaskState对Task的生命周期定义了6个状态,每种状态会做不同的处理。
Launching:Task已经从Driver侧发送给了Executor侧(被DAGScheduler调度了,Task是通过Endpoint发出,RDD和Stage由BroadCast广播)
Running:Executor正在执行Task,尝未执行完成
Finished:Task成功的被Executor执行完成
Failed:Executor 执行Failed失败,失败原因可能是FetchFailed、ExecptionFailure等
Killed:执行Task的Executor被Killed,KilledExecutorOnhost事件会导致Executo被Killed
Lost:仅用于Mesos fine-grained调度模式(Mesos fine-grained调度模式已经不推荐使用),这种状态可不考虑
代码清单:
private[spark] object TaskState extends Enumeration {
val LAUNCHING, RUNNING, FINISHED, FAILED, KILLED, LOST = Value
private val FINISHED_STATES = Set(FINISHED, FAILED, KILLED, LOST)
type TaskState = Value
//Failed包含两种状态,Lost和Failed
def isFailed(state: TaskState): Boolean = (LOST == state) || (FAILED == state)
//Finished状态包含四种状态,这点需要注意
def isFinished(state: TaskState): Boolean = FINISHED_STATES.contains(state)
}
下图为Task的状态流转,容错需要处理的状态为Failed、Killed、Lost。
我们再从Driver、Executor视角看Task从生成到执行完成经过的阶段,笔者把这个过程划分为5个阶段,分别是生成、管道化、调度、执行、完成。在Driver侧负责Task的生成、管道化、调度三个阶段,Executor侧负责Task执行、结果两个阶段。
整个过程对应的类:
Executor只负责执行Task,不负责管理Task的状态,不负责管理Task的生命周期,也不负责Task的容错处理。Executor在执行Task的过程中会把Task的状态通过StatusUpdate事件消息通过RpcEndpoint通信框架发送给Driver侧。Driver侧在收到StatusUpdate事件消息后根根据消息分类决定下一步操作。Driver端的容错处理涉及类有CoarseGrainedSchedulerBackend,TaskScheduler、DAGScheduler、TaskSetManager等,下面对这些容错处理分别进行介绍
Task 异常
执行Task的异常类型分别有TaskResultLost、ExecutorLostFailure、ExecptionFailure、FetchFailed、TaskCommitDenied,Task的容错处理其中重点是处理好这些错误。Task失败的异常均继承于TaskFailedReason。
sealed trait TaskFailedReason extends TaskEndReason {
/** Error message displayed in the web UI. */
def toErrorString: String
/**
* Whether this task failure should be counted towards the maximum number of times the task is
* allowed to fail before the stage is aborted. Set to false in cases where the task's failure
* was unrelated to the task; for example, if the task failed because the executor it was running
* on was killed.
*/
def countTowardsTaskFailures: Boolean = true
}
countTowardsTaskFailures属性值为true时,表明此类异常需要累加到Task的错误总次数里面,为false不需要累加错误次数。
异常类型 | 发生原因 |
UnknownReason | Spark-Core无法识别Task失败的原因,这类异常统称UnknownReason。比如:反序列化Task Result时类找不到异常。 |
TaskKilled | 任务被终止,需要重新调度 |
Resubmitted | 在一个Stage没有完成前,某个 Executor与Driver断联(如:网络抖动、JVM Crashed),这个Executor中的某个Task的ShuffleMapTask结果所有的因此Spark-Core需要重新调度这个Task在别的Executor上执行。 |
ExecutorLostFailure | 执行Task的Executor与Driver断联(如:网络抖动、JVM Crashed) |
ExceptionFailure | 用户代码产生的未捕获异常,也包含类似反序列化失败这样的不可恢复的异常类型 |
FetchFailed | 从一个远程Executor节点获取Shuffle过程的数据失败 |
TaskCommitedDenied | 执行Taskr的Executor向Driver提交请求,但被Driver拒绝 |
TaskResultLost | 这个任务处理成功并结束了。但计算结果丢失了(Executor的BlockManager中找不到相关结果),这种情况就是Driver侧记录的Task状态是处理成功的,但在Executor侧获取不到执行结果。
|
Task状态与异常
Task的状态由Executor在执行过程中是否有异常决定的,在执行结束后没有出现异常,状态会设置为Finished,如果有异常,会根据不同的异常类型,设置不同的状态。下图对状态和异常类型作了映射关联总结。