閱讀提示:讀者如果對Spark的背景知識不是很了解的話,建議首先閱讀《SPARK2.1.0模型設計與基本架構(上)》一文。
Spark模型設計
1. Spark編程模型
正如Hadoop在介紹MapReduce編程模型時選擇word count的例子,並且使用圖形來說明一樣,筆者對於Spark編程模型也選擇用圖形展現。
Spark 應用程序從編寫到提交、執行、輸出的整個過程如圖5所示。
圖5 代碼執行過程
圖5中描述了Spark編程模型的關鍵環節的步驟如下。
1)用戶使用SparkContext提供的API(常用的有textFile、sequenceFile、runJob、stop等)編寫Driver application程序。此外,SparkSession、DataFrame、SQLContext、HiveContext及StreamingContext都對SparkContext進行了封裝,並提供了DataFrame、SQL、Hive及流式計算相關的API。
2)使用SparkContext提交的用戶應用程序,首先會通過RpcEnv向集群管理器(Cluster Manager)注冊應用(Application)並且告知集群管理器需要的資源數量。集群管理器根據Application的需求,給Application分配Executor資源,並在Worker上啟動CoarseGrainedExecutorBackend進程(CoarseGrainedExecutorBackend進程內部將創建Executor)。Executor所在的CoarseGrainedExecutorBackend進程在啟動的過程中將通過RpcEnv直接向Driver注冊Executor的資源信息,TaskScheduler將保存已經分配給應用的Executor資源的地址、大小等相關信息。然后,SparkContext根據各種轉換API,構建RDD之間的血緣關系(lineage)和DAG,RDD構成的DAG將最終提交給DAGScheduler。DAGScheduler給提交的DAG創建Job並根據RDD的依賴性質將DAG划分為不同的Stage。DAGScheduler根據Stage內RDD的Partition數量創建多個Task並批量提交給TaskScheduler。TaskScheduler對批量的Task按照FIFO或FAIR調度算法進行調度,然后給Task分配Executor資源,最后將Task發送給Executor由Executor執行。此外,SparkContext還會在RDD轉換開始之前使用BlockManager和BroadcastManager將任務的Hadoop配置進行廣播。
3)集群管理器(Cluster Manager)會根據應用的需求,給應用分配資源,即將具體任務分配到不同Worker節點上的多個Executor來處理任務的運行。Standalone、YARN、Mesos、EC2等都可以作為Spark的集群管理器。
4)Task在運行的過程中需要對一些數據(例如中間結果、檢查點等)進行持久化,Spark支持選擇HDFS 、Amazon S3、Alluxio(原名叫Tachyon)等作為存儲。
2.RDD計算模型
RDD可以看做是對各種數據計算模型的統一抽象,Spark的計算過程主要是RDD的迭代計算過程,如圖6所示。RDD的迭代計算過程非常類似於管道。分區數量取決於Partition數量的設定,每個分區的數據只會在一個Task中計算。所有分區可以在多個機器節點的Executor上並行執行。
圖6 RDD計算模型
圖6只是簡單的從分區的角度將RDD的計算看作是管道,如果從RDD的血緣關系、Stage划分的角度來看,由RDD構成的DAG經過DAGScheduler調度后,將變成圖7所示的樣子。
圖7 DAGScheduler對由RDD構成的DAG進行調度
圖7中共展示了A、B、C、D、E、F、G一共7個RDD。每個RDD中的小方塊代表一個分區,將會有一個Task處理此分區的數據。RDD A經過groupByKey轉換后得到RDD B。RDD C經過map轉換后得到RDD D。RDD D和RDD E經過union轉換后得到RDD F。RDD B和RDD F經過join轉換后得到RDD G。從圖中可以看到map和union生成的RDD與其上游RDD之間的依賴是NarrowDependency,而groupByKey和join生成的RDD與其上游的RDD之間的依賴是ShuffleDependency。由於DAGScheduler按照ShuffleDependency作為Stage的划分的依據,因此A被划入了ShuffleMapStage 1;C、D、E、F被划入了ShuffleMapStage 2;B和G被划入了ResultStage 3。
Spark基本架構
從集群部署的角度來看,Spark集群由集群管理器(Cluster Manager)、工作節點(Worker)、執行器(Executor)、驅動器(Driver)、應用程序(Application)等部分組成,它們之間的整體關系如圖8所示。
圖8 Spark基本架構圖
下面結合圖8對這些組成部分以及它們之間的關系進行介紹。
(1)Cluster Manager
Spark的集群管理器,主要負責對整個集群資源的分配與管理。Cluster Manager在Yarn部署模式下為ResourceManager;在Mesos部署模式下為Mesos master;在Standalone部署模式下為Master。Cluster Manager分配的資源屬於一級分配,它將各個Worker上的內存、CPU等資源分配給Application,但是並不負責對Executor的資源分配。Standalone部署模式下的Master會直接給Application分配內存、CPU以及Executor等資源。目前,Standalone、YARN、Mesos、EC2等都可以作為Spark的集群管理器。
注意:這里提到了部署模式中的Standalone、Yarn、Mesos等模式,讀者暫時知道這些內容即可,本書將在第9章對它們詳細介紹。
(2)Worker
Spark的工作節點。在Yarn部署模式下實際由NodeManager替代。Worker節點主要負責以下工作:將自己的內存、CPU等資源通過注冊機制告知Cluster Manager;創建Executor;將資源和任務進一步分配給Executor;同步資源信息、Executor狀態信息給Cluster Manager等。在Standalone部署模式下,Master將Worker上的內存、CPU以及Executor等資源分配給Application后,將命令Worker啟動CoarseGrainedExecutorBackend進程(此進程會創建Executor實例)。
(3)Executor
執行計算任務的一線組件。主要負責任務的執行以及與Worker、Driver的信息同步。
(4)Driver
Application的驅動程序,Application通過Driver與Cluster Manager、Executor進行通信。Driver可以運行在Application中,也可以由Application提交給Cluster Manager並由Cluster Manager安排Worker運行。
(4)Application
用戶使用Spark提供的API編寫的應用程序,Application通過Spark API將進行RDD的轉換和DAG的構建,並通過Driver將Application注冊到Cluster Manager。Cluster Manager將會根據Application的資源需求,通過一級分配將Executor、內存、CPU等資源分配給Application。Driver通過二級分配將Executor等資源分配給每一個任務,Application最后通過Driver告訴Executor運行任務。
小結
每項技術的誕生都會由某種社會需求所驅動,Spark正是在實時計算的大量需求下誕生的。Spark借助其優秀的處理能力,可用性高,豐富的數據源支持等特點,在當前大數據領域變得火熱,參與的開發者也越來越多。Spark經過幾年的迭代發展,如今已經提供了豐富的功能。筆者相信,Spark在未來必將產生更耀眼的火花。
關於《Spark內核設計的藝術 架構設計與實現》
經過近一年的准備,基於Spark2.1.0版本的《Spark內核設計的藝術 架構設計與實現》一書現已出版發行,圖書如圖:
紙質版售賣鏈接如下: