深入理解spark之架構與原理

全面攻城發表於2018-02-02

 Spark提供了一個全面、統一的框架用於管理各種有著不同性質(文字資料、圖表資料等)的資料集和資料來源(批量資料或實時的流資料)的大資料處理的需求
官方資料介紹Spark可以將Hadoop叢集中的應用在記憶體中的執行速度提升100倍,甚至能夠將應用在磁碟上的執行速度提升10倍。

基本理念:

RDD(resillient distributed dataset):彈性分散式資料集。

Task:具體執行任務。Task分為ShuffleMapTask和ResultTask兩種。ShuffleMapTask和ResultTask分別類似於Hadoop中的Map,Reduce。

Job:使用者提交的作業。一個Job可能由一到多個Task組成。

Stage:Job分成的階段。一個Job可能被劃分為一到多個Stage。

Partition:資料分割槽。即一個RDD的資料可以劃分為多少個分割槽。

NarrowDependency:窄依賴。即子RDD依賴於父RDD中固定的Partition。NarrowDependency分為OneToOneDependency和RangeDependency兩種。

ShuffleDependency:shuffle依賴,也稱為寬依賴。即子RDD對父RDD中的所有Partition都有依賴。

DAG(Directed Acycle graph):有向無環圖。用於反映各RDD之間的依賴關係。

使用場景:

Spark適用場景:

  1. Spark是基於記憶體的迭代計算框架,適用於需要多次操作特定資料集的應用場合。需要反覆操作的次數越多,所需讀取的資料量越大,受益越大,資料量小但是計算密集度較大的場合,受益就相對較小。
  2. 由於RDD的特性,Spark不適用那種非同步細粒度更新狀態的應用,例如web服務的儲存或者是增量的web爬蟲和索引。就是對於那種增量修改的應用模型不適合。
  3. 資料量不是特別大,但是要求近實時統計分析需求

spark不適用場景:

  1. 記憶體hold不住的場景,在記憶體不足的情況下,Spark會下放到磁碟,會降低應有的效能

  2. 有高實時性要求的流式計算業務,例如實時性要求毫秒級
  3. 由於RDD設計上的只讀特點,所以Spark對於待分析資料頻繁變動的情景很難做(並不是不可以),比如題主例子裡的搜尋,假設你的資料集在頻繁變化(不停增刪改),而且又需要結果具有很強的一致性(不一致時間視窗很小),那麼就不合適了。
  4. 流線長或檔案流量非常大的資料集不適合。你會發現你的記憶體不夠用,叢集壓力大時一旦一個task失敗會導致他前面一條線所有的前置任務全部重跑,然後惡性迴圈會導致更多的task失敗,整個sparkapp效率極低。就不如MapReduce啦!

架構及生態:

Apache Spark是一個正在快速成長的開源叢集計算系統,正在快速的成長。Apache Spark生態系統中的包和框架日益豐富,使得Spark能夠進行高階資料分析。Apache Spark的快速成功得益於它的強大功能和易於使用性。相比於傳統的MapReduce大資料分析,Spark效率更高、執行時速度更快。Apache Spark 提供了記憶體中的分散式計算能力,具有Java、 Scala、Python、R四種程式語言的API程式設計介面。Spark生態系統如下圖所示:

深入理解spark之架構與原理

Spark Core:包含Spark的基本功能;尤其是定義RDD的API、操作以及這兩者上的動作。其他Spark的庫都是構建在RDD和Spark Core之上的

Spark SQL:提供通過Apache Hive的SQL變體Hive查詢語言(HiveQL)與Spark進行互動的API。每個資料庫表被當做一個RDD,Spark SQL查詢被轉換為Spark操作。

Spark Streaming:對實時資料流進行處理和控制。Spark Streaming允許程式能夠像普通RDD一樣處理實時資料

MLlib:一個常用機器學習演算法庫,演算法被實現為對RDD的Spark操作。這個庫包含可擴充套件的學習演算法,比如分類、迴歸等需要對大量資料集進行迭代的操作。

GraphX:控制圖、並行圖操作和計算的一組演算法和工具的集合。GraphX擴充套件了RDD API,包含控制圖、建立子圖、訪問路徑上所有頂點的操作

Spark架構的組成圖如下:

Spark cluster components

Cluster Manager:在standalone模式中即為Master主節點,控制整個叢集,監控worker。在YARN模式中為資源管理器

Worker節點:從節點,負責控制計算節點,啟動Executor或者Driver。

Driver: 執行Application 的main()函式

Executor:執行器,是為某個Application執行在worker node上的一個程式


Spark程式設計模型

Spark 應用程式從編寫到提交、執行、輸出的整個過程如圖所示,圖中描述的步驟如下:

1) 使用者使用SparkContext提供的API(常用的有textFile、sequenceFile、runJob、stop等)編寫Driver application程式。此外SQLContext、HiveContext及StreamingContext對SparkContext進行封裝,並提供了SQL、Hive及流式計算相關的API。

2) 使用SparkContext提交的使用者應用程式,首先會使用BlockManager和BroadcastManager將任務的Hadoop配置進行廣播。然後由DAGScheduler將任務轉換為RDD並組織成DAG,DAG還將被劃分為不同的Stage。最後由TaskScheduler藉助ActorSystem將任務提交給叢集管理器(Cluster Manager)。

3) 叢集管理器(ClusterManager)給任務分配資源,即將具體任務分配到Worker上,Worker建立Executor來處理任務的執行。Standalone、YARN、Mesos、EC2等都可以作為Spark的叢集管理器。

深入理解spark之架構與原理

spark計算模型:

RDD可以看做是對各種資料計算模型的統一抽象,Spark的計算過程主要是RDD的迭代計算過程。RDD的迭代計算過程非常類似於管道。分割槽數量取決於partition數量的設定,每個分割槽的資料只會在一個Task中計算。所有分割槽可以在多個機器節點的Executor上並行執行。

深入理解spark之架構與原理

叢集架構設計

架構


整個叢集分為 Master 節點和 Worker 節點,相當於 Hadoop 的 Master 和 Slave 節點。 Master 節點上常駐 Master 守護程式,負責管理全部的 Worker 節點。 Worker 節點上常駐 Worker 守護程式,負責與 Master 節點通訊並管理 executors。 Driver 官方解釋是 “The process running the main() function of the application and creating the SparkContext”。Application 就是使用者自己寫的 Spark 程式(driver program。


spark 執行流程與特點:

相關圖片

  1. 構建Spark Application的執行環境,啟動SparkContext
  2. SparkContext向資源管理器(可以是Standalone,Mesos,Yarn)申請執行Executor資源,並啟動StandaloneExecutorbackend,
  3. Executor向SparkContext申請Task
  4. SparkContext將應用程式分發給Executor
  5. SparkContext構建成DAG圖,將DAG圖分解成Stage、將Taskset傳送給Task Scheduler,最後由Task Scheduler將Task傳送給Executor執行
  6. Task在Executor上執行,執行完釋放所有資源


特點:

  1. 每個Application獲取專屬的executor程式,該程式在Application期間一直駐留,並以多執行緒方式執行Task。這種Application隔離機制是有優勢的,無論是從排程角度看(每個Driver排程他自己的任務),還是從執行角度看(來自不同Application的Task執行在不同JVM中),當然這樣意味著Spark Application不能跨應用程式共享資料,除非將資料寫入外部儲存系統
  2. Spark與資源管理器無關,只要能夠獲取executor程式,並能保持相互通訊就可以了
  3. 提交SparkContext的Client應該靠近Worker節點(執行Executor的節點),最好是在同一個Rack裡,因為Spark Application執行過程中SparkContext和Executor之間有大量的資訊交換
  4. Task採用了資料本地性和推測執行的優化機制

RDD執行流程:

RDD在Spark中執行大概分為以下三步:

    1. 建立RDD物件
    2. DAGScheduler模組介入運算,計算RDD之間的依賴關係,RDD之間的依賴關係就形成了DAG
    3. 每一個Job被分為多個Stage。劃分Stage的一個主要依據是當前計算因子的輸入是否是確定的,如果是則將其分在同一個Stage,避免多個Stage之間的訊息傳遞開銷深入理解spark之架構與原理 深入理解spark之架構與原理
  • 建立 RDD 上面的例子除去最後一個 collect 是個動作,不會建立 RDD 之外,前面四個轉換都會建立出新的 RDD 。因此第一步就是建立好所有 RDD( 內部的五項資訊 )?建立執行計劃 Spark 會盡可能地管道化,並基於是否要重新組織資料來劃分 階段 (stage) ,例如本例中的 groupBy() 轉換就會將整個執行計劃劃分成兩階段執行。最終會產生一個 DAG(directed acyclic graph ,有向無環圖 ) 作為邏輯執行計劃

深入理解spark之架構與原理


排程任務 將各階段劃分成不同的 任務 (task) ,每個任務都是資料和計算的合體。在進行下一階段前,當前階段的所有任務都要執行完成。因為下一階段的第一個轉換一定是重新組織資料的,所以必須等當前階段所有結果資料都計算出來了才能繼續

spark執行模式:

standalone: 獨立叢集執行模式

  • Standalone模式使用Spark自帶的資源排程框架
  • 採用Master/Slaves的典型架構,選用ZooKeeper來實現Master的HA


深入理解spark之架構與原理

yarn:

Spark on YARN模式根據Driver在叢集中的位置分為兩種模式:一種是YARN-Client模式,另一種是YARN-Cluster(或稱為YARN-Standalone模式)

Yarn-Client模式中,Driver在客戶端本地執行,這種模式可以使得Spark Application和客戶端進行互動,因為Driver在客戶端,所以可以通過webUI訪問Driver的狀態,預設是http://hadoop1:4040訪問,而YARN通過http:// hadoop1:8088訪問

  • YARN-client的工作流程步驟為:

深入理解spark之架構與原理

  • Spark Yarn Client向YARN的ResourceManager申請啟動Application Master。同時在SparkContent初始化中將建立DAGScheduler和TASKScheduler等,由於我們選擇的是Yarn-Client模式,程式會選擇YarnClientClusterScheduler和YarnClientSchedulerBackend
  • ResourceManager收到請求後,在叢集中選擇一個NodeManager,為該應用程式分配第一個Container,要求它在這個Container中啟動應用程式的ApplicationMaster,與YARN-Cluster區別的是在該ApplicationMaster不執行SparkContext,只與SparkContext進行聯絡進行資源的分派
  • Client中的SparkContext初始化完畢後,與ApplicationMaster建立通訊,向ResourceManager註冊,根據任務資訊向ResourceManager申請資源(Container)
  • 一旦ApplicationMaster申請到資源(也就是Container)後,便與對應的NodeManager通訊,要求它在獲得的Container中啟動CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend啟動後會向Client中的SparkContext註冊並申請Task
  • client中的SparkContext分配Task給CoarseGrainedExecutorBackend執行,CoarseGrainedExecutorBackend執行Task並向Driver彙報執行的狀態和進度,以讓Client隨時掌握各個任務的執行狀態,從而可以在任務失敗時重新啟動任務
  • 應用程式執行完成後,Client的SparkContext向ResourceManager申請登出並關閉自己

Spark Cluster模式:

  • 在YARN-Cluster模式中,當使用者向YARN中提交一個應用程式後,YARN將分兩個階段執行該應用程式:
    1. 第一個階段是把Spark的Driver作為一個ApplicationMaster在YARN叢集中先啟動;
    2. 第二個階段是由ApplicationMaster建立應用程式,然後為它向ResourceManager申請資源,並啟動Executor來執行Task,同時監控它的整個執行過程,直到執行完成

    深入理解spark之架構與原理


    • Spark Yarn Client向YARN中提交應用程式,包括ApplicationMaster程式、啟動ApplicationMaster的命令、需要在Executor中執行的程式等
    • ResourceManager收到請求後,在叢集中選擇一個NodeManager,為該應用程式分配第一個Container,要求它在這個Container中啟動應用程式的ApplicationMaster,其中ApplicationMaster進行SparkContext等的初始化
    • ApplicationMaster向ResourceManager註冊,這樣使用者可以直接通過ResourceManage檢視應用程式的執行狀態,然後它將採用輪詢的方式通過RPC協議為各個任務申請資源,並監控它們的執行狀態直到執行結束
    • 一旦ApplicationMaster申請到資源(也就是Container)後,便與對應的NodeManager通訊,要求它在獲得的Container中啟動CoarseGrainedExecutorBackend,CoarseGrainedExecutorBackend啟動後會向ApplicationMaster中的SparkContext註冊並申請Task。這一點和Standalone模式一樣,只不過SparkContext在Spark Application中初始化時,使用CoarseGrainedSchedulerBackend配合YarnClusterScheduler進行任務的排程,其中YarnClusterScheduler只是對TaskSchedulerImpl的一個簡單包裝,增加了對Executor的等待邏輯等
    • ApplicationMaster中的SparkContext分配Task給CoarseGrainedExecutorBackend執行,CoarseGrainedExecutorBackend執行Task並向ApplicationMaster彙報執行的狀態和進度,以讓ApplicationMaster隨時掌握各個任務的執行狀態,從而可以在任務失敗時重新啟動任務
    • 應用程式執行完成後,ApplicationMaster向ResourceManager申請登出並關閉自己

    深入理解spark之架構與原理

    參考地址:https://www.cnblogs.com/tgzhu/p/5818374.html


    相關文章