Spark是一個分佈式系統,也是集多個功能模塊於一身的統一平臺。它基於一個內核模塊衍生出機器學習,實時流計算,OLAP,和圖數據處理等模塊,如圖1-1-1所示。本書主要介紹Spark內核模塊的實現原理。java
圖1-1-1 spark功能模塊python
從圖1-1-1中能夠看出Spark內核模塊是基礎層,它是全部上層功能模塊的基礎。全部上層的功能模塊都使用Spark內核模塊提供的接口來實現其功能。sql
Spark應用能夠在多種資源管理框架中執行,因爲在Spark應用執行前,資源管理框架的各個服務已經啓動(Local模式除外),因此,區分Spark應用執行時建立的服務和資源框架提供的服務很是重要。編程
圖1-1-2 Spark應用執行架構
性能優化
圖1-1-2是Spark應用執行時的基本架構圖。圖中用兩種顏色進行了標識,其中淺綠色的方塊是資源管理框架的服務,好比:YARN模式的Resource Manager(對應Cluster Manager)和Node Manager(對應Worker節點);又好比,Standalone模式下的Master和Worker服務。要注意的是:這些服務在Spark應用程序提交和執行前就一直處於運行狀態,Spark應用運行運行在資源管理平臺之上,當執行Spark應用程序時,會向資源管理器(Cluster Manager)申請運行資源。數據結構
而淡藍色的模塊是Spark應用執行時才啓動的服務或對象,好比:Spark Session和Executor,當Spark應用執行完成後,這些服務或對象以及運行Spark應用所佔用的資源就會被回收。架構
下表是圖1-1-2中各個角色的簡要說明,後面還會針對每一個角色進行詳細分析。框架
角色名機器學習 |
歸屬分佈式 |
說明 |
Cluster Manager |
資源管理框架 |
負責爲運行在資源管理跨框架上的應用程序分配資源。 |
Worker |
資源管理框架 |
根據Cluster Manager的指令分配資源,執行應用程序,釋放資源。 |
Driver |
Spark應用 |
Spark應用程序的Driver端,Spark應用由Driver驅動執行。 |
Executor |
Spark應用 |
Spark應用程序的執行端,在執行Spark應用時建立,執行完成後被回收。 |
SparkSession |
Spark應用 |
Spark應用的核心元素,經過它來初始化Spark應用的環境。在Spark應用執行時建立。執行完成後關閉。 |
隨着分佈式應用愈來愈多,爲了更好的利用和管理CPU和內存資源,誕生了許多分佈式資源管理框架。經過這些資源管理框架能夠更好的爲分佈式應用分配和管理計算資源。好比:Hadoop使用了YARN做爲資源管理框架,另外還誕生了開源的Mesos等;隨着雲計算的發展,誕生了Kubernetes等。
Spark也支持了這幾種主流的資源管理框架,Spark應用能夠運行在這幾種資源管理框架之上。另外,Spark還本身實現了一套資源管理框架。在執行Spark應用時,能夠指定使用哪一種資源管理框架。
表1-1-1是各類資源管理框架的角色和Spark應用執行架構中角色的對應關係表。因爲Spark對Kubernetes的支持還處於試驗階段,因此,這裏暫不介紹。
資源管理框架 |
Cluster Manager |
Worker |
Spark自帶 |
Master服務 |
Worker服務 |
Yarn |
Resouce Manager服務 |
Node Manager服務 |
Mesos |
Mesos master服務 |
Mesos Agent服務 |
表1-1-1 資源管理框架和Spark架構角色對應關係
Spark應用(Application)是用戶基於Spark編寫的應用程序。它由一個Driver進程和一組Executor進程組成,它們都是在Spark應用執行時建立,應用執行完成後即被回收。Spark應用可使用多種語言編寫:python,R,java,scala等。
Spark應用能夠運行在圖1-1-1所描述的三種資源管理框架中,也能夠以Local模式運行。在Local模式下Driver和Executor都在同一個JVM中運行,Local模式的詳細運行原理在「Local模式」一節中進行分析。
Driver負責啓動Spark應用,驅動應用的執行。它對Spark應用的整個執行過程進行管控,它是Spark應用程序的"master"(注意不要和資源管理框架的master混淆。這樣稱呼主要由於:在Spark應用執行時,Driver端會啓動不少服務的master端,這些服務的slave端運行在Executor上,這些服務的slave會向Driver端對應的master註冊或彙報運行狀態信息)。
Driver經過運行Spark應用的main函數來執行應用,從應用開始執行到把Task提交到Executor端有不少步驟,這些步驟都在Driver端完成。Driver端會把應用進行編排,最終會生成一個個的Task,並提交給Executor去執行,當Task被提交到Executor端後,Driver會和Executor進行通訊,實時監控執行狀態。總的來講Driver須要完成如下幾個方面的工做:
經過運行Spark應用的main函數來啓動Spark應用;
向資源管理平臺申請資源,並在Worker節點上啓動Executor;
建立SparkSession(包括SparkContext和SparkEnv),並對Spark應用進行規劃,編排,最後提交到Executor端執行;
收集Spark應用的執行狀態,並返回執行結果;
注意,Driver也能夠運行在資源管理框架的某個節點上(例如:yarn cluster模式下運行在Application Master中 )。
因爲Driver端是Spark應用執行的核心,有時候咱們須要對其資源進行設置,能夠經過如下方式來對Driver的內存和CPU個數進行設置:
配置Driver的內存:
經過spark-submit’s --driver-memory 選項進行設置;
經過spark.driver.memory參數進行配置,默認是:1G;
配置Driver使用的CPU個數:
經過spark-submit’s --driver-cores選項進行設置;
經過spark.driver.cores參數進行設置,默認是1;
1)Executor的建立
Executor是在執行Spark應用時由執行後臺服務建立。建立多少個Executor,每一個Executor使用多少內存和CPU均可以經過參數進行指定。但注意:Local運行模式和其餘模式不一樣,Local模式下只會建立一個Executor。
2)Executor的職責
Executor是執行Spark應用的容器,顧名思義,它的職責就是根據Driver端的要求來啓動執行線程,執行任務,並返回執行結果。
3)Executor的資源配置
每次執行Spark任務時,均可以對Executor的個數,每一個Executor的CPU和內存大小等進行配置。Executor的這些配置很是關鍵,會直接影響Spark任務的執行效率。
Job是Spark應用執行層次結構中的最高層元素。咱們知道,Spark應用的經過Driver端的程序來驅動應用的執行,在Spark應用程序中,每一個RDD的Action操做都對應一個Job。
每一個Job會劃分紅一系列的Stage, Stage的數量依賴於發生過多少次shuffle操做。
每一個Job都被劃分爲一些較小的任務集(Task Set),這些任務集稱爲Stage。這些Stage相互依賴,從而造成一個Stage的DAG圖(有向無環圖)。
發送給Executor端執行的工做單元。每一個RDD的分區對應一個Task,也就是說,觸發任務執行的RDD有多少個分區就會建立多少個Task。Task的建立是在Driver端完成,而Task的執行在Executor端。Executor會建立一個線程池來執行Task,每一個Task對應一個執行線程。
SparkSession是Spark SQL的入口點。它是您在開發Spark SQL應用程序時首先要建立的對象之一。在建立SparkSession時,會同時建立SparkContext和SparkEnv。
在SparkSession中提供了多種建立Dataset和DataFrame的方法。
該進程運行應用程序的main()函數並建立SparkContext。在建立SparkContext時,會爲Spark應用準備執行環境,包括各類服務的初始化,各類工具類的建立等。
在建立SparkContext時會和ResourceManager通訊來申請任務執行資源,當SparkContext建立完成時Spark應用的執行環境就準備完成了,包括:Driver端完成各類初始化服務的啓動,Worker端的完成Executor的建立。
Spark提供了3種編程接口:RDD,Dataframe,SparkSql,三者的區別與聯繫以下表:
RDD |
DataFrame |
Sparksql |
|
不可變 |
Yes |
Yes |
Yes |
表結構 |
No |
Yes |
Yes |
Spark V1 |
Yes |
Yes |
Yes |
Spark V2 |
Yes |
Yes |
Yes |
性能優化 |
No |
Yes |
Yes |
數據類型支持 |
Yes |
No |
Yes |
語法錯誤檢查 |
編譯時 |
編譯時 |
編譯時 |
錯誤分析 |
編譯時 |
運行時 |
編譯時 |
語言支持 |
都支持 |
Python,java,scala,R |
從上表咱們能夠看出:
1)DataFrame和SparkSql是帶有schema的結構化數據結構,由於有了Schema,因此會讓數據更容易理解和使用。
2)DataFrame和SparkSql會對用戶編寫的代碼進行優化,而Spark不會對RDD進行優化,由於它已是最底層的基本元素了。實際上,在執行DataFrame和SparkSql任務時,會通過從邏輯執行計劃到物理執行計劃,再到RDD的代碼生成等一系列的步驟,而這些步驟的目的就是爲了獲得RDD的最優化執行代碼。
3)另外還要注意,DataFrame支持的語言是有限制的。
本文介紹了Spark的基本架構,和Spark應用的基本組成。經過本文能夠對Spark有一個整體的概念,這對於理解其原理打下一個基礎。