Spark 架構概述

本文目錄

  • 介紹 Spark 生態。
  • 介紹 Spark 基本概念和經常使用術語。
  • 介紹 Spark 的執行原理和架構設計。
  • 介紹 Spark-Yarn 部署模式。
  • 介紹 Saprk RDD 運行原理。

Spark 生態

  • Spark Core:包含了 Spark 的基礎 API,好比對於 RDD 的操做 API,其餘的 Spark 庫也都是構建在 Spark Core 的基礎上。
  • Spark Sql:包含了對於 Hive Sql 的操做,能夠將 Hive Sql 轉換成 Spark Rdd 操做。
  • Spark Streaming:提供了對於實時數據進行處理的方式。
  • MLib:包含了經常使用的機器學習算法實現,對於常見的分類和迴歸操做,能夠對大量數據進分佈式行迭代的操做。
  • GraphX:對圖操做的工具集合。

p.s: 關於 Spark Sql/Spark Streaming/MLib 後續幾篇文章在單獨介紹,本文只先簡單概述一下 Spark 的架構設計。算法

基礎術語

在 Spark 中,被提交的程序叫作 Application,一個 Application 由多個 Job 組成,一個 Job 能夠分解成多個 Stage,一個 Stage 又能夠分解成多個 Task,而後將 Task 放在 Executor 進程上面運行。緩存

  • Application:用戶編寫的 Spark 程序,能夠理解爲兩部分,一部分是 Driver 代碼,另一部分是 Executor 代碼。
  • Driver:Driver 能夠理解爲 Application 的 main 函數,會建立一個 SparkContext,SparkContext 負責與 Cluster Manager 通訊,進行資源申請、任務的分配和監控等。
  • Cluster Manager:負責集羣中資源的分配,目前主要有四種模式:
    • local:運行在本地非分佈式部署。
    • Standalon:Spark 原生的資源管理。
    • Apache Mesos。
    • Yarn:Yarn 中的 ResourceManager,下文將對 Spark-On-Yarn 作詳細介紹。
  • Worker:集羣中能夠運行 Application 代碼的節點,在 Spark On Yarn 模式下能夠理解爲 NodeManager 節點。
  • Executor:運行在 Worker 上的一個進程,該進程能夠負責多線程運行 task。
  • Job:一個 Application 由多個 Job 組成。
  • Stage:一個 Job 通過 DAG(DAGScheduler) 分解,能夠拆分紅多個 Stage。
  • Task:一個 Stage 能夠拆解成多個 Task,而後放到 Executor 上面運行。

執行過程

  • 當一個 Spark 應用被提交時,首先須要爲這個應用構建起基本的運行環境,即由任務控制節點(Driver)建立一個 SparkContext,由 SparkContext 負責和資源管理器(Cluster Manager)的通訊以及進行資源的申請、任務的分配和監控等。SparkContext 會向資源管理器註冊並申請運行 Executor 的資源。
  • 資源管理器爲 Executor 分配資源,並啓動 Executor 進程,Executor 運行狀況將隨着「心跳」發送到資源管理器上。
  • SparkContext 根據 RDD 的依賴關係構建 DAG 圖,DAG 圖提交給 DAG 調度器(DAGScheduler)進行解析,將 DAG 圖分解成多個「階段」(每一個階段都是一個任務集),而且計算出各個階段之間的依賴關係,而後把一個個「任務集」提交給底層的任務調度器(TaskScheduler)進行處理;Executor 向 SparkContext 申請任務,任務調度器將任務分發給 Executor 運行,同時,SparkContext 將應用程序代碼發放給 Executor。
  • 任務在 Executor 上運行,把執行結果反饋給任務調度器,而後反饋給 DAG 調度器,運行完畢後寫入數據並釋放全部資源。

總結

總結而言,Spark 運行架構具備如下特色:網絡

  • 每一個應用都有本身專屬的 Executor 進程,Executor 進程以多線程的方式運行任務,減小了多進程任務頻繁的啓動開銷,使得任務執行變得很是高效和可靠;
  • Spark 運行過程與資源管理器無關,只要可以獲取 Executor 進程並保持通訊便可;
  • Executor 上有一個 BlockManager 存儲模塊,相似於鍵值存儲系統(把內存和磁盤共同做爲存儲設備),在處理迭代計算任務時,不須要把中間結果寫入到HDFS等文件系統,而是直接放在這個存儲系統上,後續有須要時就能夠直接讀取;在交互式查詢場景下,也能夠把表提早緩存到這個存儲系統上,提升讀寫 IO 性能;
  • 任務採用了數據本地性和推測執行等優化機制。數據本地性是儘可能將計算移到數據所在的節點上進行,即「計算向數據靠攏」,由於移動計算比移動數據所佔的網絡資源要少得多。並且,Spark 採用了延時調度機制,能夠在更大的程度上實現執行過程優化。好比,擁有數據的節點當前正被其餘的任務佔用,那麼,在這種狀況下是否須要將數據移動到其餘的空閒節點呢?答案是不必定。由於,若是通過預測發現當前節點結束當前任務的時間要比移動數據的時間還要少,那麼,調度就會等待,直到當前節點可用。

Spark On Yarn

Spark On Yarn 模式根據 Driver 在集羣中的位置分爲兩種模式:一種是 Yarn-Client 模式,另一種是 Yarn-Cluster 模式。多線程

Yarn-Client 模式

  • Spark Yarn Client 向 Yarn 的 ResourceManager 申請啓動 Application Master。同時在 SparkContext 中建立 DAGScheduler 和 TASKScheduler 等。
  • ResourceManager 收到請求後,在集羣中選擇一個 NodeManager,爲該應用程序第一個 Container,要求它在這個 Container 中啓動應用程序的 ApplicationMaster。
  • Client 中的 SparkContext 初始完畢後,與 ApplicationMaster 創建通信,向 ResourceManager 註冊,根據任務信息向 ResourceManager 申請 Container。
  • 一旦 ApplicationMaster 申請到資源,也就是 Container 之後,便與對應的 NodeManger 通訊,要求它在得到的 Container 中啓動 CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend 啓動後會向 Client 中的 SparkContext 註冊並申請 Task。
  • Client 中的 SparkContext 分配 Task 給 CoarseGrainedExecutorBackend 執行,CoarseGrainedExecutorBackend 運行 Task 並向 Driver 彙報運行狀態和監控。
  • 應用程序完成後,Client 的 SparkContext 向 ResourceManager 申請註銷並關閉本身。

Yarn-Cluster 模式

在 Yarn-Cluster 模式中,當用戶向 Yarn 提交一個應用程序後,Yarn 將分兩個階段運用該 Application:架構

  1. 把 Spark 的 Driver 做爲一個 ApplicationMaster 在 Yarn 集羣中先啓動。
  2. 由 ApplicationMaster 建立應用程序,而後爲它向 ResourceManager 申請資源,並啓動 Executor 來運行 Task,同時監控它的整個運行過程,直到運行完成。

在 YARN 中,每一個 Application 實例都有一個 ApplicationMaster 進程,它是 Application 啓動的第一個容器。它負責和 ResourceManager 打交道並請求資源,獲取資源以後告訴 NodeManager 爲其啓動 Container。從深層次的含義講 YARN-Cluster 和 YARN-Client 模式的區別其實就是 ApplicationMaster 進程的區別。機器學習

YARN-Cluster 模式下,Driver 運行在 Application Master 中,它負責向 YARN 申請資源,並監督做業的運行情況。當用戶提交了做業以後,就能夠關掉 Client,做業會繼續在 YARN 上運行,於是 YARN-Cluster 模式不適合運行交互類型的做業; YARN-Client 模式下,Application Master 僅僅向 YARN 請求 Executor,Client 會和請求的 Container 通訊來調度他們工做,也就是說 Client 不能離開。分佈式

RDD

一個 RDD 就是一個只讀分佈式對象集合,一個 RDD 能夠分紅多個分區,每一個分區就是一個數據集片斷,不一樣的分區能夠保存到不一樣的節點上。Spark RDD 能夠分爲兩類:函數

  1. 轉換操做(好比 map/filter/groupBy/join)接受 rdd 並返回 rdd。
  2. 行動操做(好比 count/collect)接受 rdd 可是不返回 rdd。Spark 中的 rdd 採用了惰性調用,真正的計算髮生在行動操做,對於行動以前的轉換操做,Spark 只是記錄下轉換操做的依賴關係。

寬依賴和窄依賴

  1. 窄依賴表示爲,一個父 RDD 分區對應與一個子 RDD 分區,或者多個 RDD 分區對應一個子 RDD 分區。好比 map/filter/union。
  2. 寬依賴表示爲,一個父 RDD 分區對應一個子 RDD 的多個分區。好比 groupByKey、sortByKey 等操做。

階段劃分(DAG)

Spark 經過分析各個 RDD 的依賴關係生成了 DAG,再經過分析各個 RDD 中的分區之間的依賴關係來決定如何劃分階段,具體劃分方法是:在 DAG 中進行反向解析,遇到寬依賴就斷開,遇到窄依賴就把當前的 RDD 加入到當前的階段中;將窄依賴儘可能劃分在同一個階段中,能夠實現流水線計算。工具

如圖所示,假設從 HDFS 中讀入數據生成 3 個不一樣的 RDD(A、C和E),經過一系列轉換操做後再將計算結果保存回 HDFS。對 DAG 進行解析時,在依賴圖中進行反向解析,因爲從 RDD A 到 RDD B 的轉換以及從 RDD B 和F 到 RDD G的 轉換,都屬於寬依賴,所以,在寬依賴處斷開後能夠獲得三個階段,即階段一、階段2 和階段3。能夠看出,在階段2 中,從 map 到 union 都是窄依賴,這兩步操做能夠造成一個流水線操做,好比,分區7 經過 map 操做生成的分區9,能夠不用等待分區8 到分區10 這個轉換操做的計算結束,而是繼續進行 union 操做,轉換獲得分區13,這樣流水線執行大大提升了計算的效率。性能

相關文章
相關標籤/搜索