深刻理解spark之架構與原理

 Spark提供了一個全面、統一的框架用於管理各類有着不一樣性質(文本數據、圖表數據等)的數據集和數據源(批量數據或實時的流數據)的大數據處理的需求
官方資料介紹Spark能夠將Hadoop集羣中的應用在內存中的運行速度提高100倍,甚至可以將應用在磁盤上的運行速度提高10倍。html

基本理念:

RDD(resillient distributed dataset):彈性分佈式數據集。node

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

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之間的依賴關係。app

使用場景:

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 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計算模型:

RDD能夠看作是對各類數據計算模型的統一抽象,Spark的計算過程主要是RDD的迭代計算過程。RDD的迭代計算過程很是相似於管道。分區數量取決於partition數量的設定,每一個分區的數據只會在一個Task中計算。全部分區能夠在多個機器節點的Executor上並行執行。

集羣架構設計

架構


整個集羣分爲 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之間的消息傳遞開銷
  • 建立 RDD 上面的例子除去最後一個 collect 是個動做,不會建立 RDD 以外,前面四個轉換都會建立出新的 RDD 。所以第一步就是建立好全部 RDD( 內部的五項信息 )?建立執行計劃 Spark 會盡量地管道化,並基因而否要從新組織數據來劃分 階段 (stage) ,例如本例中的 groupBy() 轉換就會將整個執行計劃劃分紅兩階段執行。最終會產生一個 DAG(directed acyclic graph ,有向無環圖 ) 做爲邏輯執行計劃


調度任務 將各階段劃分紅不一樣的 任務 (task) ,每一個任務都是數據和計算的合體。在進行下一階段前,當前階段的全部任務都要執行完成。由於下一階段的第一個轉換必定是從新組織數據的,因此必須等當前階段全部結果數據都計算出來了才能繼續

spark運行模式:

standalone: 獨立集羣運行模式

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


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 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 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申請註銷並關閉本身

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

    相關文章
    相關標籤/搜索