1. 程式人生 > >Spark 生態系統元件

Spark 生態系統元件

引言:隨著大資料技術的發展,實時流計算、機器學習、圖計算等領域成為較熱的研究方向,而Spark作為大資料處理的“利器”有著較為成熟的生態圈,能夠一站式解決類似場景的問題。那麼Spark生態系統中有哪些元件你知道嗎?下面讓我們跟著本文一同瞭解下 這些不可或缺的元件。本文選自《圖解Spark:核心技術與案例實戰》。

  Spark 生態系統以Spark Core 為核心,能夠讀取傳統檔案(如文字檔案)、HDFS、Amazon S3、Alluxio 和NoSQL 等資料來源,利用Standalone、YARN 和Mesos 等資源排程管理,完成應用程式分析與處理。這些應用程式來自Spark 的不同元件,如Spark Shell 或Spark Submit 互動式批處理方式、Spark Streaming 的實時流處理應用、Spark SQL 的即席查詢、取樣近似查詢引擎BlinkDB 的權衡查詢、MLbase/MLlib 的機器學習、GraphX 的圖處理和SparkR 的數學計算等,如下圖所示,正是這個生態系統實現了“One Stack to Rule Them All”目標。 
圖片描述

Spark Core

  Spark Core 是整個BDAS 生態系統的核心元件,是一個分散式大資料處理框架。Spark Core提供了多種資源排程管理,通過記憶體計算、有向無環圖(DAG)等機制保證分散式計算的快速,並引入了RDD 的抽象保證資料的高容錯性,其重要特性描述如下。

  • Spark Core提供了多種執行模式,不僅可以使用自身執行模式處理任務,如本地模式、Standalone,而且可以使用第三方資源排程框架來處理任務,如YARN、MESOS等。相比較而言,第三方資源排程框架能夠更細粒度管理資源。
  • Spark Core提供了有向無環圖(DAG)的分散式平行計算框架,並提供記憶體機制來支援多次迭代計算或者資料共享,大大減少迭代計算之間讀取資料的開銷,這對於需要進行多次迭代的資料探勘和分析效能有極大提升。另外,在任務處理過程中移動計算而非移動資料,RDDPartition 可以就近讀取分散式檔案系統中的資料塊到各個節點記憶體中進行計算。
  • 在Spark 中引入了RDD的抽象,它是分佈在一組節點中的只讀物件集合,這些集合是彈性的,如果資料集一部分丟失,則可以根據“血統”對它們進行重建,保證了資料的高容錯性。

Spark Streaming

  Spark Streaming 是一個對實時資料流進行高吞吐、高容錯的流式處理系統,可以對多種資料來源(如Kafka、Flume、Twitter 和ZeroMQ 等)進行類似Map、Reduce 和Join 等複雜操作,並將結果儲存到外部檔案系統、資料庫或應用到實時儀表盤,如下圖。 
圖片描述
  相比其他的處理引擎要麼只專注於流處理,要麼只負責批處理(僅提供需要外部實現的流處理API 介面),而Spark Streaming 最大的優勢是提供的處理引擎和RDD 程式設計模型可以同時進行批處理與流處理。 
  對於傳統流處理中一次處理一條記錄的方式而言,Spark Streaming 使用的是將流資料離散化處理(Discretized Streams),通過該處理方式能夠進行秒級以下的資料批處理。在SparkStreaming 處理過程中,Receiver 並行接收資料,並將資料快取至Spark 工作節點的記憶體中。經過延遲優化後,Spark 引擎對短任務(幾十毫秒)能夠進行批處理,並且可將結果輸出至其他系統中。與傳統連續運算元模型不同,其模型是靜態分配給一個節點進行計算,而Spark 可基於資料的來源以及可用資源情況動態分配給工作節點。 
圖片描述


  使用離散化流資料(DStreaming),Spark Streaming 將具有如下特性。

  • 動態負載均衡:Spark Streaming 
    將資料劃分為小批量,通過這種方式可以實現對資源更細粒度的分配。例如,傳統實時流記錄處理系統在輸入資料流以鍵值進行分割槽處理情況下,如果一個節點計算壓力較大超出了負荷,該節點將成為瓶頸,進而拖慢整個系統的處理速度。而在Spark Streaming中,作業任務將會動態地平衡分配給各個節點,如圖,即如果任務處理時間較長,分配的任務數量將少些;如果任務處理時間較短,則分配的任務資料將更多些。

圖片描述

  • 快速故障恢復機制:在節點出現故障的情況下,傳統流處理系統會在其他的節點上重啟失敗的連續運算元,並可能重新執行先前資料流處理操作獲取部分丟失資料。在此過程中只有該節點重新處理失敗的過程,只有在新節點完成故障前所有計算後,整個系統才能夠處理其他任務。在Spark中,計算將分成許多小的任務,保證能在任何節點執行後能夠正確進行合併。因此,在某節點出現的故障的情況,這個節點的任務將均勻地分散到叢集中的節點進行計算,相對於傳遞故障恢復機制能夠更快地恢復。

圖片描述
  批處理、流處理與互動式分析的一體化:Spark Streaming 是將流式計算分解成一系列短小的批處理作業,也就是把Spark Streaming 的輸入資料按照批處理大小(如幾秒)分成一段一段的離散資料流(DStream),每一段資料都轉換成Spark 中的RDD,然後將Spark Streaming 中對DStream 流處理操作變為針對Spark 中對RDD 的批處理操作。另外,流資料都儲存在Spark 節點的記憶體裡,使用者便能根據所需進行互動查詢。正是利用了Spark 這種工作機制將批處理、流處理與互動式工作結合在一起。

Spark SQL

  Spark SQL 的前身是Shark,它釋出時Hive 可以說是SQL on Hadoop 的唯一選擇(Hive 負責將SQL 編譯成可擴充套件的MapReduce 作業),鑑於Hive 的效能以及與Spark 的相容,Shark 由此而生。 
  Shark 即Hive on Spark,本質上是通過Hive 的HQL 進行解析,把HQL 翻譯成Spark 上對應的RDD 操作,然後通過Hive 的Metadata 獲取資料庫裡的表資訊,實際為HDFS 上的資料和檔案,最後由Shark 獲取並放到Spark 上運算。Shark 的最大特性就是速度快,能與Hive 的完全相容,並且可以在Shell 模式下使用rdd2sql 這樣的API,把HQL 得到的結果集繼續在Scala環境下運算,支援使用者編寫簡單的機器學習或簡單分析處理函式,對HQL 結果進一步分析計算。 
  在2014 年7 月1 日的Spark Summit 上,Databricks 宣佈終止對Shark 的開發,將重點放到Spark SQL 上。在此次會議上,Databricks 表示,Shark 更多是對Hive 的改造,替換了Hive 的物理執行引擎,使之有一個較快的處理速度。然而,不容忽視的是,Shark 繼承了大量的Hive程式碼,因此給優化和維護帶來大量的麻煩。隨著效能優化和先進分析整合的進一步加深,基於MapReduce 設計的部分無疑成為了整個專案的瓶頸。因此,為了更好的發展,給使用者提供一個更好的體驗,Databricks 宣佈終止Shark 專案,從而將更多的精力放到Spark SQL 上。 
  Spark SQL 允許開發人員直接處理RDD,同時也可查詢在 Hive 上存在的外部資料。SparkSQL 的一個重要特點是能夠統一處理關係表和RDD,使得開發人員可以輕鬆地使用SQL 命令進行外部查詢,同時進行更復雜的資料分析。

  Spark SQL 的特點如下。

  • 引入了新的RDD 型別SchemaRDD,可以像傳統資料庫定義表一樣來定義SchemaRDD。 SchemaRDD由定義了列資料型別的行物件構成。SchemaRDD 既可以從RDD 轉換過 來,也可以從Parquet 檔案讀入,還可以使用HiveQL從Hive 中獲取。
  • 內嵌了Catalyst 查詢優化框架,在把SQL 解析成邏輯執行計劃之後,利用Catalyst 包裡的一些類和介面,執行了一些簡單的執行計劃優化,最後變成RDD 的計算。
  • 在應用程式中可以混合使用不同來源的資料,如可以將來自HiveQL的資料和來自SQL的資料進行Join 操作。 Shark的出現使得SQL-on-Hadoop 的效能比Hive 有了10~100 倍的提高,那麼,擺脫了 Hive 的限制,Spark SQL的效能又有怎麼樣的表現呢?雖然沒有Shark 相對於Hive 那樣矚目的 效能提升,但也表現得優異,如圖(其中,右側資料為Spark SQL)。

圖片描述
  為什麼Spark SQL 的效能會得到這麼大的提升呢?主要是Spark SQL 在以下幾點做了優化。

  • 記憶體列儲存(In-Memory Columnar Storage):Spark SQL 的表資料在記憶體中儲存不是採用原生態的JVM物件儲存方式,而是採用記憶體列儲存。
  • 位元組碼生成技術(Bytecode Generation):Spark 1.1.0 在Catalyst 模組的Expressions 
    增加了Codegen 模組,使用動態位元組碼生成技術,對匹配的表示式採用特定的程式碼動態編譯。另外對SQL 表示式都做了CG 優化。CG優化的實現主要還是依靠Scala 2.10執行時的反射機制(Runtime Reflection)。
  • Scala 程式碼優化:Spark SQL 在使用Scala編寫程式碼的時候,儘量避免低效的、容易GC的程式碼;儘管增加了編寫程式碼的難度,但對於使用者來說介面統一。

BlinkDB

  BlinkDB 是一個用於在海量資料上執行互動式SQL 查詢的大規模並行查詢引擎,它允許使用者通過權衡資料精度來提升查詢響應時間,其資料的精度被控制在允許的誤差範圍內。為了達到這個目標,BlinkDB 使用如下核心思想:

  • 自適應優化框架,從原始資料隨著時間的推移建立並維護一組多維樣本。
  • 動態樣本選擇策略,選擇一個適當大小的示例,該示例基於查詢的準確性和響應時間的緊迫性。和傳統關係型資料庫不同,BlinkDB是一個互動式查詢系統,就像一個蹺蹺板,使用者需要在查詢精度和查詢時間上做權衡;如果使用者想更快地獲取查詢結果,那麼將犧牲查詢結果的精度;反之,使用者如果想獲取更高精度的查詢結果,就需要犧牲查詢響應時間。下圖為BlinkDB架構。

圖片描述

MLBase/MLlib

  MLBase 是Spark 生態系統中專注於機器學習的元件,它的目標是讓機器學習的門檻更低,讓一些可能並不瞭解機器學習的使用者能夠方便地使用MLBase。MLBase 分為4 個部分:MLRuntime、MLlib、MLI 和ML Optimizer。

  • MLRuntime:是由Spark Core 提供的分散式記憶體計算框架,執行由Optimizer優化過的演算法進行資料的計算並輸出分析結果。
  • MLlib:是Spark 實現一些常見的機器學習演算法和實用程式,包括分類、迴歸、聚類、協同過濾、降維以及底層優化。該演算法可以進行可擴充。
  • MLI:是一個進行特徵抽取和高階ML 程式設計抽象演算法實現的API 或平臺。
  • MLOptimizer:會選擇它認為最適合的已經在內部實現好了的機器學習演算法和相關引數,來處理使用者輸入的資料,並返回模型或其他幫助分析的結果。

圖片描述
  MLBase 的核心是其優化器(ML Optimizer),它可以把宣告式的任務轉化成複雜的學習計劃,最終產出最優的模型和計算結果。MLBase 與其他機器學習Weka 和Mahout 不同,三者各有特色,具體內容如下。

  • MLBase 基於Spark,它是使用的是分散式記憶體計算的;Weka 是一個單機的系統,而Mahout 是使用MapReduce 
    進行處理資料(Mahout 正向使用Spark 處理資料轉變)。
  • MLBase 是自動化處理的;Weka 和Mahout 都需要使用者具備機器學習技能,來選擇自己想要的演算法和引數來做處理。
  • MLBase 提供了不同抽象程度的介面,可以由使用者通過該介面實現演算法的擴充套件。

GraphX

  GraphX 最初是伯克利AMP 實驗室的一個分散式圖計算框架專案,後來整合到Spark 中成為一個核心元件。它是Spark 中用於圖和圖平行計算的API,可以認為是GraphLab 和Pregel 在Spark 上的重寫及優化。跟其他分散式圖計算框架相比,GraphX 最大的優勢是:在Spark 基礎上提供了一棧式資料解決方案,可以高效地完成圖計算的完整的流水作業。 
  GraphX 的核心抽象是Resilient Distributed Property Graph,一種點和邊都帶屬性的有向多重圖。GraphX 擴充套件了Spark RDD 的抽象,它有Table 和Graph 兩種檢視,但只需要一份物理儲存,兩種檢視都有自己獨有的操作符,從而獲得了靈活操作和執行效率。GraphX 的整體架構中大部分的實現都是圍繞Partition 的優化進行的,這在某種程度上說明了,點分割的儲存和相應的計算優化的確是圖計算框架的重點和難點。 
GraphX 的底層設計有以下幾個關鍵點。 
(1)對Graph 檢視的所有操作,最終都會轉換成其關聯的Table 檢視的RDD 操作來完成。這樣對一個圖的計算,最終在邏輯上,等價於一系列RDD 的轉換過程。因此,Graph 最終具備了RDD 的3 個關鍵特性:Immutable、Distributed 和Fault-Tolerant。其中最關鍵的是Immutable(不變性)。邏輯上,所有圖的轉換和操作都產生了一個新圖;物理上,GraphX 會有一定程度的不變頂點和邊的複用優化,對使用者透明。 
(2)兩種檢視底層共用的物理資料,由RDD[Vertex-Partition]和RDD[EdgePartition]這兩個RDD 組成。點和邊實際都不是以表Collection[tuple] 的形式儲存的, 而是由VertexPartition/EdgePartition 在內部儲存一個帶索引結構的分片資料塊,以加速不同檢視下的遍歷速度。不變的索引結構在RDD 轉換過程中是共用的,降低了計算和儲存開銷。 
(3)圖的分散式儲存採用點分割模式,而且使用partitionBy 方法,由使用者指定不同的劃分策略(PartitionStrategy)。劃分策略會將邊分配到各個EdgePartition,頂點Master 分配到各個VertexPartition,EdgePartition 也會快取本地邊關聯點的Ghost 副本。劃分策略的不同會影響到所需要快取的Ghost 副本數量,以及每個EdgePartition 分配的邊的均衡程度,需要根據圖的結構特徵選取最佳策略。

SparkR

  R 是遵循GNU 協議的一款開源、免費的軟體,廣泛應用於統計計算和統計製圖,但是它只能單機執行。為了能夠使用R 語言分析大規模分散式的資料,伯克利分校AMP 實驗室開發了SparkR,並在Spark 1.4 版本中加入了該元件。通過SparkR 可以分析大規模的資料集,並通過R Shell 互動式地在SparkR 上執行作業。SparkR 特性如下:

  • 提供了Spark 中彈性分散式資料集(RDDs)的API,使用者可以在叢集上通過R Shell互動性地執行Spark 任務。
  • 支援序化閉包功能,可以將使用者定義函式中所引用到的變數自動序化傳送到叢集中其他的機器上。
  • SparkR 還可以很容易地呼叫R 開發包,只需要在叢集上執行操作前用includePackage讀取R 開發包就可以了。

下為SparkR 的處理流程示意圖。 
圖片描述

Alluxio

  Alluxio 是一個分散式記憶體檔案系統,它是一個高容錯的分散式檔案系統,允許檔案以記憶體的速度在叢集框架中進行可靠的共享,就像Spark 和 MapReduce 那樣。Alluxio 是架構在最底層的分散式檔案儲存和上層的各種計算框架之間的一種中介軟體。其主要職責是將那些不需要落地到DFS 裡的檔案,落地到分散式記憶體檔案系統中,來達到共享記憶體,從而提高效率。同時可以減少記憶體冗餘、GC 時間等。 
  和Hadoop 類似,Alluxio 的架構是傳統的Master-Slave 架構,所有的Alluxio Worker 都被Alluxio Master 所管理,Alluxio Master 通過Alluxio Worker 定時發出的心跳來判斷Worker 是否已經崩潰以及每個Worker 剩餘的記憶體空間量,為了防止單點問題使用了ZooKeeper 做了HA。 
  Alluxio 具有如下特性。

  • AVA-Like File API:Alluxio 提供類似Java File 類的API。
  • 相容性:Alluxio 實現了HDFS 介面,所以Spark 和MapReduce 程式不需要任何修改即可執行。
  • 可插拔的底層檔案系統:Alluxio是一個可插拔的底層檔案系統,提供容錯功能,它將記憶體資料記錄在底層檔案系統。它有一個通用的介面,可以很容易地插入到不同的底層檔案系統。目前支援HDFS、S3、GlusterFS和單節點的本地檔案系統,以後將支援更多的檔案系統。Alluxio 所支援的應用如下。

圖片描述