目錄
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,如果有異常,會根據不同的異常類型,設置不同的狀態。下圖對狀態和異常類型作了映射關聯總結。