贅述
本系列的文章將會從spark源碼的角度來分析spark任務(wù)提交集群到運行結(jié)束這個過程的處理邏輯,所以對Spark編程的熟練度要求比較高浩淘。
Spark是基于內(nèi)存的大數(shù)據(jù)處理計算引擎捌朴。 使用 Scala語言實現(xiàn),可以像操作本地集合對象一樣輕松地操作分布式數(shù)據(jù)集张抄,其將 Scala 用作其應(yīng)用程序框架砂蔽,同時支持java,python開發(fā)。這篇文章主要對spark的任務(wù)流程做一個簡單的深度解析署惯。
正解
下面將從某一臺提交spark應(yīng)用的機器講解整個任務(wù)流程左驾,
1、spark任務(wù)提交
首先通過azkaban等任務(wù)調(diào)度平臺(spark-submit)將spark的jar包(application)提交到集群運行后,這時會啟動一個Driver進程(client和cluster的Driver位置是不同的)诡右,Driver進程會執(zhí)行application應(yīng)用程序安岂。
2、SparkContext初始化
spark主類的代碼首先是構(gòu)造SparkConf帆吻,再構(gòu)造SparkContext,如圖:
sparkContext初始化域那,最重要的就是構(gòu)造DAGScheduler和TaskScheduler。構(gòu)建TaskScheduler之后猜煮,TaskScheduler通過它對應(yīng)的一個后臺進程琉雳,去負(fù)責(zé)連接master,向master申請注冊application友瘤,master接收到application注冊的請求之后,會使用資源調(diào)度算法檐束,在spark集群的worker上辫秧,為這個application啟動多個Executor。executor啟動之后會自己反向注冊到TaskScheduler被丧,Executor全部反向注冊到Driver之后盟戏,Driver會結(jié)束SparkConctext初始化,繼續(xù)執(zhí)行我們自己的代碼甥桂。
3柿究、構(gòu)建job及其劃分
Spark代碼每觸發(fā)一次action就會創(chuàng)建一個job,DAGScheduler將Job劃分成由Stage組成的DAG后黄选,就根據(jù)Stage的具體類型來生成ShuffleMapTask和ResultTask蝇摸,然后使用TaskSet對其進行封裝,最后調(diào)用TaskScheduler的submitTasks方法提交具體的TaskSet办陷。TaskScheduler把taskset里的每一個task提交到executor上執(zhí)行貌夕。executor每接收到一個Task,都會用TaskRunner來封裝task民镜,然后從線程池里取出一個線程啡专,執(zhí)行這個task。TaskRunner把spark代碼的算子或者函數(shù)拷貝制圈、反序列化们童,然后執(zhí)行task。
所以鲸鹦,整個spark應(yīng)用程序的執(zhí)行慧库,就是stage分批次作為taskset提交到executor執(zhí)行,每個task針對RDD的一個partition亥鬓,執(zhí)行我們定義的算子和函數(shù)完沪,以此類推,直到所有的操作執(zhí)行結(jié)束。
具體的細(xì)節(jié)算法覆积,會在后續(xù)的文章中詳細(xì)解讀