天天看點

35.Spark系統運作内幕機制循環流程

一:TaskScheduler原了解密

1,  DAGScheduler在送出TaskSet給底層排程器的時候是面向接口TaskScheduler的,這符合面向對象中依賴抽象而不依賴的原則,帶來底層資源排程器的可插拔性,導緻Spark可以運作的衆多的資源排程器模式上,例如Standalone、Yarn、Mesos、Local、EC2、其它自定義的資源排程器;在Standalone的模式下我們聚焦于TaskSchedulerImpl;

2,  在SparkContext執行個體化的時候通過createTaskScheduler來建立TaskSchedulerImpl和SparkDEploySchedulerBackend:

caseSPARK_REGEX(sparkUrl) =>

valscheduler = new TaskSchedulerImpl(sc)

valmasterUrls = sparkUrl.split(",").map("spark://" + _)

valbackend = new SparkDeploySchedulerBackend(scheduler, sc, masterUrls)

scheduler.initialize(backend)

(backend, scheduler)

在TaskSchedulerImpl的initialize方法中把SparkDeploySchedulerBackend傳進來進而指派為TaskSchedulerImpl的backend;在TaskSchedulerImpl調用start方法的時候會調用backend.start方法,在start方法中會最終注冊應用程式

3,  TaskScheduler的核心任務是送出TaskSet到叢集運算并彙報結果

a)         為TaskSet建立和維護一個TaskSetManager并追蹤任務的本地性以及錯誤資訊;

b)         遇到Straggle任務會放到其它的節點進行重試;

c)         向DAGScheduler彙報執行情況,包括在Shuffle輸出lost的時候報告fetch failed錯誤等資訊;

4,  TaskScheduler内部會握有SchedulerBackend,從Standalone的模式來講具體實作是SparkDeploySchedulerBackend;

5,  SparkDeploySchedulerBackend在啟動的時候構造了AppClient執行個體并在該執行個體start的時候啟動了ClientEndpoint這個消息循環體,ClientEndpoint在啟動的會向Master注冊目前程式;而SparkDeploySchedulerBackend的父類CoarseGrainedSchedulerBackend在start的時候會執行個體化類型為DriverEndpoint(這就是我們程式運作時候的經典對象 Driver)的消息循環體,SparkDeploySchedulerBackend專門負責收集Worker上的資源資訊,當ExecutorBackend啟動的時候會發送RegisteredExecutor資訊向DriverEndpoint注冊,此時SparkDeploySchedulerBackend就掌握了目前應用程式擁有的計算資源,TaskScheduler就是通過SparkDeploySchedulerBackend擁有的計算資源來具體運作Task;

6,  SparkContext、DAGScheduler、TaskSchedulerImpl、SparkDeploySchedulerBackend在應用程式啟動的時候隻執行個體化一次,應用程式存在期間始終存在這些對象;

大總結:在SparkContext執行個體化的時候調用createTaskScheduler來建立TaskSchedulerImpl和SparkDeploySchedulerBackend,同時在SparkContext執行個體化的時候會調用TaskSchedulerImpl的start,在start方法中會調用SparkDeploySchedulerBackend的start,在該start方法中會建立AppClient對象并調用AppClient對象的start方法,在該start方法中會建立ClientEndpoint,在建立ClientEndpoint會傳入Command來指定具體為目前應用程式啟動的Executor進行的入口類的名稱為CoarseGrainedExecutorBackend,然後ClientEndpoint啟動并通過tryRegisterMaster來注冊目前的應用程式到Master中,Master接受到注冊資訊後如何可以運作程式,則會為該程式生産Job ID并通過schedule來配置設定計算資源,具體計算資源的配置設定是通過應用程式的運作方式、Memory、cores等配置資訊來決定的,最後Master會發送指令給Worker,Worker中為目前應用程式配置設定計算資源時會首先配置設定ExecutorRunner,ExecutorRunner内部會通過Thread的方式建構ProcessBuilder來啟動另外一個JVM程序,這個JVM程序啟動時候加載的main方法所在的類的名稱就是在建立ClientEndpoint時傳入的Command來指定具體名稱為CoarseGrainedExecutorBackend的類,此時JVM在通過ProcessBuilder啟動的時候獲得了CoarseGrainedExecutorBackend後加載并調用其中的main方法,在main方法中會執行個體化CoarseGrainedExecutorBackend本身這個消息循環體,而CoarseGrainedExecutorBackend在執行個體化的時候會通過回調onStart向DriverEndpoint發送RegisterExecutor來注冊目前的CoarseGrainedExecutorBackend,此時DriverEndpoint收到到該注冊資訊并儲存在了SparkDeploySchedulerBackend執行個體的記憶體資料結構中,這樣Driver就獲得了計算資源!

繼續閱讀