spark應用執行機制分析
前段時間一直在編寫指標代碼,一直采用的是--deploy-mode client方式開發測試,因此執行沒遇到什么問題,但是放到生產上采用--master yarn-cluster方式運行,那問題就開始陸續暴露出來了。因此寫一篇文章分析並記錄一下spark的幾種運行方式。
1.spark應用的基本概念
spark運行模式分為:Local(本地idea上運行),Standalone,yarn,mesos等,這里主要是討論一下在yarn上的運行方式,因為這也是最常見的生產方式。
根據spark Application的Driver Program是否在集群中運行,spark應用的運行方式又可以分為Cluster模式和Client模式。
spark應用涉及的一些基本概念:
1.mater:主要是控制、管理和監督整個spark集群
2.client:客戶端,將用應用程序提交,記錄着要業務運行邏輯和master通訊。
3.sparkContext:spark應用程序的入口,負責調度各個運算資源,協調各個work node上的Executor。主要是一些記錄信息,記錄誰運行的,運行的情況如何等。這也是為什么編程的時候必須要創建一個sparkContext的原因了。
4.Driver Program:每個應用的主要管理者,每個應用的老大,有人可能問不是有master么怎么還來一個?因為master是集群的老大,每個應用都歸老大管,那老大瘋了。因此driver負責具體事務運行並跟蹤,運行Application的main()函數並創建sparkContext。
5.RDD:spark的核心數據結構,可以通過一系列算子進行操作,當Rdd遇到Action算子時,將之前的所有的算子形成一個有向無環圖(DAG)。再在spark中轉化成為job,提交到集群執行。一個app可以包含多個job
6.worker Node:集群的工作節點,可以運行Application代碼的節點,接收mater的命令並且領取運行任務,同時匯報執行的進度和結果給master,節點上運行一個或者多個Executor進程。
7.exector:為application運行在workerNode上的一個進程,該進程負責運行Task,並且負責將數據存在內存或者磁盤上。每個application都會申請各自的Executor來處理任務。
spark應用(Application)執行過程中各個組件的概念:
1.Task(任務):RDD中的一個分區對應一個task,task是單個分區上最小的處理流程單元。
2.TaskSet(任務集):一組關聯的,但相互之間沒有Shuffle依賴關系的Task集合。
3.Stage(調度階段):一個taskSet對應的調度階段,每個job會根據RDD的寬依賴關系被切分很多Stage,每個stage都包含 一個TaskSet。
4.job(作業):由Action算子觸發生成的由一個或者多個stage組成的計算作業。
5.application:用戶編寫的spark應用程序,由一個或者多個job組成,提交到spark之后,spark為application分派資源,將程序轉換並執行。
6.DAGScheduler:根據job構建基於stage的DAG,並提交stage給TaskScheduler。
7.TaskScheduler:將Taskset提交給Worker Node集群運行並返回結果。
spark基本概念之間的關系
一個Application可以由一個或者多個job組成,一個job可以由一個或者多個stage組成,其中stage是根據寬窄依賴進行划分的,一個stage由一個taskset組成,一個TaskSET可以由一個到多個task組成。
應用提交與執行
spark使用driver進程負責應用的解析,切分Stage並且調度task到Executor執行,包含DAGscheduler等重要對象。Driver進程的運行地點有如下兩種:
1.driver進程運行在client端,對應用進行管理監控。
2.Master節點指定某個Worker節點啟動Driver進程,負責監控整個應用的執行。
driver運行在client
用戶啟動Client端,在client端啟動Driver進程。在Driver中啟動或實例化DAGScheduler等組件。
1.driver在client啟動,做好准備工作,計划好任務的策略和方式(DAGScheduler)后向Master注冊並申請運行Executor資源。
2.Worker向Master注冊,Master通過指令讓worker啟動Executor。
3.worker收到指令后創建ExecutorRunner線程,進而ExecutorRunner線程啟動executorBackend進程。
4.ExecutorBackend啟動后,向client端driver進程內的SchedulerBackend注冊,這樣dirver進程就可以發現計算資源了。
5.Driver的DAGScheduler解析應用中的RDD DAG並生成相應的Stage,每個Stage包含的TaskSet通過TaskScheduler分配給Executor,在Exectutor內部啟動線程池並行化執行Task,同事driver會密切注視,如果發現哪個execuctor執行效率低,會分配其他exeuctor頂替執行,觀察誰的效率更高(推測執行)。
6.計划中的所有stage被執行完了之后,各個worker匯報給driver,同事釋放資源,driver確定都做完了,就向master匯報。同時driver在client上,應用的執行進度clinet也知道了。
Driver運行在Worker節點
用戶啟動客戶端,客戶端提交應用程序給Master
1.Master調度應用,指定一個worker節點啟動driver,即Scheduler-Backend。
2.worker接收到Master命令后創建driverRunner線程,在DriverRunner線程內創建SchedulerBackend進程,Dirver充當整個作業的主控進程。
3.Master指定其他Worker節點啟動Exeuctor,此處流程和上面相似,worker創建ExecutorRunner線程,啟動ExecutorBackend進程。
4.ExecutorBackend啟動后,向client端driver進程內的SchedulerBackend注冊,這樣dirver進程就可以發現計算資源了。
5.Driver的DAGScheduler解析應用中的RDD DAG並生成相應的Stage,每個Stage包含的TaskSet通過TaskScheduler分配給Executor,在Exectutor內部啟動線程池並行化執行Task,同事driver會密切注視,如果發現哪個execuctor執行效率低,會分配其他exeuctor頂替執行,觀察誰的效率更高(推測執行)。
6.計划中的所有stage被執行完了之后,各個worker匯報給driver,同事釋放資源,driver確定都做完了,就向master匯報。客戶也會跳過master直接和drive通訊了解任務的執行進度。