spark任务shell运行_了解Spark 应用的一生
Spark從被創造至今已經成為了大數據計算引擎中不可或缺的一環,雖然Spark非常的優秀但相比于其他的開源框架依然有著比較高的學習門檻,希望能夠通過一種有結構性的,簡單直接的方式,為Spark的初學者入門。
核心概念講解
Spark 應用的架構
Driver
Driver 是整體Spark Application的架構中最重要的一個進程。為了便于理解,我們可以將Driver理解為是一個建筑工地的包工頭,他了解整個項目的實施步驟與實施內容。它主要負責分派任務,監督任務的進程,同時還需要時刻關心項目需要的建筑材料是否充分。
Executor
Executor 是除了Drvier以外負責執行任務的進程。這些任務都由Driver來指定。Executor可以被理解為包工頭下面的工人,他們不需要太多思考,而是專注于完成指定的任務。他們只需要接受任務,執行,并將執行后的狀態與結果返回即可。
Cluster Manager
Cluster Manager的概念比以上的概念稍微較難理解一些,Cluster Manager搭建了Spark Application與具體的物理機器的橋梁。如果將Spark Application理解為一個施工項目的話,那么Cluster Mangager可以理解為是一個建筑材料管理者。一個施工項目的完成需要提供足夠的建材支持執行,而當需要這些資源的時候,便需要與Cluster Manager交流。當然這只是為了便于理解而做的類比。真正的Cluster Manager中也會有自己的結構,也是一個Master/Workor的結構。這樣的結構是為了更好的管理分布式的集群的物理機器。我們可以通過下圖對Cluster Mangager有一個了解。現在Spark支持Standalone, Mesos, Yarn 三種方式,K8s會在Spark3之后支持。
Spark 執行模式
在理解了一個Spark Application里面的組成部分之后,我們來看看Spark Application能夠執行的模式
Cluster Mode
Cluster Mode是Spark Application最常用的模式。在生產環境除非特殊原因都會采用Cluster的模式來執行。在Cluster mode下,用戶提交一個Jar,pyton script或者R sciprt給Cluster Manager。之后Cluster Manager在某一個Workor節點上啟動Driver的進程。在Cluster Mode下,Cluster manager負責維持所有Spark應用進程。下圖便解釋了Cluster mode執行時的狀態。Cluster Manager選取一個Workor節點跑Driver,之后再分配其他Worker跑其余的Executor。
Client Mode
Client Mode與Cluster Mode基本一致除了Driver進程并非由Cluster Manager來管理,而是繼續跑在提交任務的機器上。這也就意味著,Driver進程將由提交任務的客戶端來維持狀態。Cluster Manager只是負責維持Executor的狀態。這些維持Driver的節點,也被叫做Edge Node或者gateway Machines。下圖便解釋了Client Mode的運行機制。
Local Mode
Local Mode是一種為了測試與開發Spark應用而存在的模式。它與前兩種截然不同。Local模式在一臺物理機器上運行,同時Executor與Driver也從進程變為線程。在生產環境中幾乎沒有不會使用local 模式。
小結
我們不妨思考一下,Spark為什么會創建出三種不同的運行模式。什么時候又會使用什么樣的模式。Cluster的模式適用于大部分應用場景,可以將它理解為一種離線提交任務的方式。Client模式非常適合shell, notebook這一類需要一直有一個主線程維持著的應用。而Local模式基本只適合測試的場景。
Spark 應用的執行過程
了解了Spark系統的組成部分,我們來看一個在Cluster Mode下跑的Spark Application的過程。
第一步, 任務請求
我們一般通過Spark-submit來提交一個Spark 應用,提交的時候需要提供已經編譯好的Jar包或者是python script,等這取決于不同的語言而不同。
通過上圖可以看到,執行這一步任務的進程還是在你自己本地的機器上,它需要負責給Cluster Manager發送請求,表明需要的資源大小。我們現在假設我們有足夠的資源,因此Cluster Manager接受了我們的請求,并尋找了一個Worker Node將Driver跑起來。如果一切順利,那么此本地進程就會結束退出。
以下是一個任務提交的示例
./bin/spark-submit --class <main-class> --master <master-url> --deploy-mode cluster --conf <key>=<value> ... # other options <application-jar> [application-arguments]第二步,任務啟動
當Driver進程開始之后,Driver會擁有一個SparkSession的對象。SparkSession定義了運行這個Spark Application所需要的環境信息。這包含了用多少資源,與Cluster Manager的溝通方式等。這些大部分都是在Spark-submit的時候可以進行設置的內容。
在這個過程中,Driver通過SparkSession這個對象,向Cluster Manager請求資源并建立起這個任務需要的集群,這樣一個可以用于執行Spark Application的集群便準備好了。這里需要注意,當Cluster Manager在分配了資源之后,它會將這些信息給到Driver,之后Driver便可以直接與這些Executor交流。之后除非有新的資源請求,不然就不用再找Cluster Manager了。
第三步,任務執行
執行階段我們之后會將其中涉及的概念與過程詳細展開。現在我們只需要知道這時候Driver已經掌握了足夠的信息來執行應用了。所以會開始分配executor到不同的Worker node上去。
我們需要注意這時候整體的控制權都是Driver手里,這個時候Cluster Manager只需要維持著Driver進程的狀態即可,Cluster Manager并不感知任務的具體內容。
任務完成
Driver的退出便標志著應用的完成,Driver退出時的狀態也會同時傳給Cluster Manager。這時候Cluster Manager會負責將之前分配的資源回收,并將Driver返回的狀態返回。
Spark 應用內部的過程
接下來我們仔細看看Spark Application在執行的階段內部都在發生著什么。為了能夠清楚的講清楚其中的過程,我們需要先引入Spark Application中的一些新的概念。
Spark Session
在Spark應用的一開始便是獲取一個Spark Session.如果是使用Spark-Shell,或者Zepplion等工具,你可能沒有意識到這個Session已經在你啟動Shell的時候獲得了。由于Spark版本的不同,初始化Spark Session的方式也經歷了很多的變化,由于我們旨在講明白Spark Application的內部運行流程,就不在Spark Session的方面進行過多的描述。我們只需要了解我們需要獲取SparkSession,之后才能獲得不同的Context對象來進行Spark Application的開發。我們可以調用SparkSQL的服務,也可以調用底層的RDD的服務。這些都由不同的業務需求而確定。
Logical Instructions
無論你使用什么語言進行Spark Application的開發,最終都會轉化為一個Logical Instruction的計劃,然后再變為一個物理執行計劃。如果你想要更加直觀的了解執行計劃,你可以打開Spark的UI。這時候我們便需要繼續介紹一下Spark Job的組成了。
在介紹Spark的Job組成之前,我們需要再引入兩個概念,一個是transformation,一個是shuffle。這對應著在Spark中兩種不同的數據變換邏輯。如果對Map-Reduce有了解的話那么就不難理解,Transformation可以理解為Mapper能夠完成的邏輯,而Shuffle就是需要Reducer才能完成的邏輯。我們之后會將為什么這兩類運算對于Spark的計劃來說非常的重要。
Spark Job
Spark Job在Spark Application中對應的就是一個Action的操作。這時又需要引入Spark的Lazy Evaluation的機制。Spark只有在需要獲取結果的時候才會進行運算,在這之前只會保留執行的計劃而不會調用任何計算的邏輯。
一個Job是有很多的Stage組成的,而一個Stage會包含若干個Task。
Spark Stage
一個Stage可以理解為是一組能夠被并行執行的Task的集合,一個Shuffle的操作對應一個Stage。Spark之所以執行的速度比Map-reduce要優秀,就是因為它能夠做良好的優化,能夠合理的將一個計算任務進行整合。舉個例子如果你的操作都是select, filter等,那么他們會被整合在一個Stage當中去完成。而整合的極限便是如果你需要做不同的Shuffle的操作,比如Sort, Grouping。那么Spark便會分開不同的Stage來執行。
Spark Tasks
一個Task就是Spark執行中的最小單元,它跑在一臺機器上。有多少的Task需要被執行,是有多少的partition來決定的。這里不做過多的贅述。我們只要理解Task是最小的執行單元便可以。
Spark為什么快如閃電
1. Pipelining
Pipeling是Spark Application中最具特色的部分,大部分select, filter的操作都會通過pipeling的方式放在一個Stage中執行。在這樣的執行中會盡量的使用內存而非存儲,也正是因為這樣的優化使得Spark在執行很多相同的任務中有著更好的表現。
2. Shuffle Persistence
當Spark需要做一個Shuffle的作業時,Spark會先將輸入落盤。這樣的選擇不僅是為了以后做shuffle時的方便,同時它還帶來了一個額外的好處,便是因為shuffle之前的內容已經落盤,所以如果重新執行這個任務的話,已經落盤的部分會自動的跳過。
總結
我們分別講解了Spark集群的架構,一個Spark Application如何利用分布式的架構執行,以及在執行的過程中Spark是如何處理內部的應用的。略顯粗淺,但基本涵蓋了Spark 應用的方方面面。可以算是Spark應用理解的啟蒙讀物吧。
Reference
[Spark 權威指南]
總結
以上是生活随笔為你收集整理的spark任务shell运行_了解Spark 应用的一生的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前段react技术架构图_基于 Reac
- 下一篇: android studio cmake