SparkContext解析
1、SparkContext概述
Spark的程序編寫是基于SparkContext的,體現在2方面:①Spark編程的核心基礎(RDD),第一個RDD是由SparkContext創建的;②Spark程序的調度優化也是基于SparkContext,RDD在一開始不會立即運行,會交給框架,主要是SparkContext。
Spark程序的注冊是在SparkContext實例化時候生成的對象來完成的,也就是SchedulerBackend。
Spark程序運行的時候通過Cluster Manager獲得具體的計算資源,也是通過SparkContext產生的對象SchedulerBackend來獲取的。
SparkContext崩潰或者結束的時候整個Spark程序也結束了。
?
2、SparkContext中的三大核心對象
SparkContext創建的時候有4大核心:DAGScheduler,TaskScheduler,SchedulerBackend和MapOutputTrackerMaster。
DAGScheduler:面向Job的Stage的高層調度器;
TaskScheduler:是一個接口,根據具體的Cluster Manager的不同會有不同的實現;
SchedulerBackend:是一個接口根據具體的Cluster Manager的不同會有不同的實現,有三大核心功能:①負責與Master連接注冊當前程序,②接收集群中為當前應用程序而分配的計算資源Executor的注冊,并管理Executor。③負責發送Task到具體的Executor執行;
MapOutputTrackerMaster:負責Shuffle中數據輸出和讀取的管理。
3、?SparkContext源碼
(1)SparkContext的默認構造器必須傳入Sparkconf
(2)在SparkContext實例化的時候,默認構造器中所有不在方法中的內容都會被實例化,很多成員都會被賦值,其中有一個關鍵的代碼createTaskScheduler,他調用的時候返回了SchedulerBackend和TaskScheduler具體的實例,然后基又構建了DAGScheduler。
(3)進入createTaskScheduler方法中,他這里面根據不同的模式local模式或者其他模式進行不同的處理。默認情況下local模式task失敗不重試,其他模式下失敗可以重試。
以Standlone模式進行解讀,源碼如下,根據傳進的url,首先創建TaskSchedulerImpl(底層調度器的核心和靈魂),創建TaskSchedulerImpl的時候必須創建一個Schedulerbackend,在TaskSchedulerImpl.initialize的時候將Schedulerbackend他作為一個參數傳入。StandaloneSchedulerBackend是被TaskSchedulerImpl來管理的。
然后進入到TaskSchedulerImpl的initialize方法中,這個主要是確定任務具體的調度方式,這里有兩種方式FIFO(默認方式,先進先出的方式)和FAIR。在TaskSchedulerImpl實例調用initialize時首先構建一個調度池SchedulerPool。
(4)createTaskScheduler執行完后返回的TaskScheduler實例為TaskSchedulerImpl,Scheduler的實例為StandaloneSchedulerBackend。代碼繼續往下走執行_taskScheduler.start(),因為taskScheduler返回的實例是TaskSchedulerImpl,所以調用TaskSchedulerImpl的start方法。
start方法里面調用的是它管理的StandaloneSchedulerBackend的start方法。
(5)在StandaloneSchedulerBackend的start方法中有個Commond比較關鍵,我們的StandaloneSchedulerBackend向我們的集群進行注冊的時候,會把commond傳遞給master,master會到worker讓worker去啟動具體進程資源的時候,具體進程的主類的名字,就叫CoarseGrainedExecutorBackend。
(6)CoarseGrainedExecutorBackend是有main方法的入口類,這個就是我們的executor所在進程的入口,我們修改指令就可以修改框架,用自己實現的ExecutorBackend。
在他的main方法中執行run方法的時候
在run方法中new出了CoarseGrainedExecutorBackend這個類的實例
注意:在啟動CoarseGrainedExecutorBackend之后就會啟動executor,executor啟動之后轉過來向driver注冊,這個話是的。要先注冊成功才會分配executor
(7)回到StandaloneSchedulerBackend中,從commond往下走,start的時候new了一個StandaloneAppClient。
進入到StandaloneAppClient這個類中,參數有RpcEnv,mater數組,應用程序的description,還有一個監聽器,集群發送事件的時候會被回調
在里面有個重要的內部類ClientEndpoint,在start方法中new出它
在ClientEndpoint啟動的時候會有registerWithMaster。這時候開始注冊,在注冊的時候變成tryRegisterAllMasters,AllMasters是因為有的時候會有多個master,實際上生產環境一定有多個master,做HA。
我們創建一個線程池,在tryRegisterAllMasters注冊的時候,從registerMasterThreadPool拿一個線程去注冊
在tryRegisterAllMasters是注冊給master,所以這里有master的引用,然后就send一個消息過去。這邊會發送一個RegisterApplication,他是case class,里面描述了我們應用程序的相關信息,包括名稱,使用最大cpu個數,還有每個executor使用的memory的內容等,這里的command就是剛才的command,還有appUiUrl是web上面顯示的url
(8)轉過來就是交給我們的master去注冊,master在收到RegisterApplication的消息之后,通過給worker發送指令啟動executor,其實是executorbackend進程去啟動executor的。這些所有的executor都要向SchedulerBackend去注冊。
4、流程圖
?
?
?
?
?
?
?
?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的SparkContext解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PL/SQL程序设计以及安全管理实验遇到
- 下一篇: Flink的异步I/O及Future和C