Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

網易雲社群發表於2019-02-26

此文已由作者嶽猛授權網易雲社群釋出。

歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。

2.Spark Streaming架構及特性分析

2.1 基本架構

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

基於是spark core的spark streaming架構。

Spark Streaming是將流式計算分解成一系列短小的批處理作業。這裡的批處理引擎是Spark,也就是把Spark Streaming的輸入資料按照batch size(如1秒)分成一段一段的資料(Discretized Stream),每一段資料都轉換成Spark中的RDD(Resilient Distributed Dataset),然後將Spark Streaming中對DStream的Transformation操作變為針對Spark中對RDD的Transformation操作,將RDD經 過操作變成中間結果儲存在記憶體中。整個流式計算根據業務的需求可以對中間的結果進行疊加,或者儲存到外部裝置。

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

簡而言之,Spark Streaming把實時輸入資料流以時間片Δt (如1秒)為單位切分成塊,Spark Streaming會把每塊資料作為一個RDD,並使用RDD操作處理每一小塊資料。每個塊都會生成一個Spark Job處理,然後分批次提交job到叢集中去執行,執行每個job的過程和真正的spark 任務沒有任何區別。

JobScheduler

負責job的排程

JobScheduler是SparkStreaming 所有Job排程的中心, JobScheduler的啟動會導致ReceiverTracker和JobGenerator的啟動。ReceiverTracker的啟動導致執行在Executor端的Receiver啟動並且接收資料,ReceiverTracker會記錄Receiver接收到的資料meta資訊。JobGenerator的啟動導致每隔BatchDuration,就呼叫DStreamGraph生成RDD Graph,並生成Job。JobScheduler中的執行緒池來提交封裝的JobSet物件(時間值,Job,資料來源的meta)。Job中封裝了業務邏輯,導致最後一個RDD的action被觸發,被DAGScheduler真正排程在Spark叢集上執行該Job。

JobGenerator

負責Job的生成

通過定時器每隔一段時間根據Dstream的依賴關係生一個一個DAG圖。

ReceiverTracker

負責資料的接收,管理和分配

ReceiverTracker在啟動Receiver的時候他有ReceiverSupervisor,其實現是ReceiverSupervisorImpl, ReceiverSupervisor本身啟動的時候會啟動Receiver,Receiver不斷的接收資料,通過BlockGenerator將資料轉換成Block。定時器會不斷的把Block資料通過BlockManager或者WAL進行儲存,資料儲存之後ReceiverSupervisorImpl會把儲存後的資料的後設資料Metadate彙報給ReceiverTracker,其實是彙報給ReceiverTracker中的RPC實體ReceiverTrackerEndpoint,主要。

2.2 基於Yarn層面的架構分析

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

上圖為spark on yarn 的cluster模式,Spark on Yarn啟動後,由Spark AppMaster中的driver(在AM的裡面會啟動driver,主要是StreamingContext物件)把Receiver作為一個Task提交給某一個Spark Executor;Receive啟動後輸入資料,生成資料塊,然後通知Spark AppMaster;Spark AppMaster會根據資料塊生成相應的Job,並把Job的Task提交給空閒Spark Executor 執行。圖中藍色的粗箭頭顯示被處理的資料流,輸入資料流可以是磁碟、網路和HDFS等,輸出可以是HDFS,資料庫等。對比Flink和spark streaming的cluster模式可以發現,都是AM裡面的元件(Flink是JM,spark streaming是Driver)承載了task的分配和排程,其他container承載了任務的執行(Flink是TM,spark streaming是Executor),不同的是spark streaming每個批次都要與driver進行通訊來進行重新排程,這樣延遲性遠低於Flink。

具體實現

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

圖2.1 Spark Streaming程式轉換為DStream Graph

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

圖2.2 DStream Graph轉換為RDD的Graph

Spark Core處理的每一步都是基於RDD的,RDD之間有依賴關係。下圖中的RDD的DAG顯示的是有3個Action,會觸發3個job,RDD自下向上依 賴,RDD產生job就會具體的執行。從DSteam Graph中可以看到,DStream的邏輯與RDD基本一致,它就是在RDD的基礎上加上了時間的依賴。RDD的DAG又可以叫空間維度,也就是說整個 Spark Streaming多了一個時間維度,也可以成為時空維度,使用Spark Streaming編寫的程式與編寫Spark程式非常相似,在Spark程式中,主要通過操作RDD(Resilient Distributed Datasets彈性分散式資料集)提供的介面,如map、reduce、filter等,實現資料的批處理。而在Spark Streaming中,則通過操作DStream(表示資料流的RDD序列)提供的介面,這些介面和RDD提供的介面類似。Spark Streaming把程式中對DStream的操作轉換為DStream Graph,圖2.1中,對於每個時間片,DStream Graph都會產生一個RDD Graph;針對每個輸出操作(如print、foreach等),Spark Streaming都會建立一個Spark action;對於每個Spark action,Spark Streaming都會產生一個相應的Spark job,並交給JobScheduler。JobScheduler中維護著一個Jobs佇列, Spark job儲存在這個佇列中,JobScheduler把Spark job提交給Spark Scheduler,Spark Scheduler負責排程Task到相應的Spark Executor上執行,最後形成spark的job。

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

圖2.3時間維度生成RDD的DAG

Y軸就是對RDD的操作,RDD的依賴關係構成了整個job的邏輯,而X軸就是時間。隨著時間的流逝,固定的時間間隔(Batch Interval)就會生成一個job例項,進而在叢集中執行。

程式碼實現

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

基於spark 1.5的spark streaming原始碼解讀,基本架構是沒怎麼變化的。

2.3 元件棧

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

支援從多種資料來源獲取資料,包括Kafk、Flume、Twitter、ZeroMQ、Kinesis 以及TCP sockets,從資料來源獲取資料之後,可以使用諸如map、reduce、join和window等高階函式進行復雜演算法的處理。最後還可以將處理結果 儲存到檔案系統,資料庫和現場儀表盤。在“One Stack rule them all”的基礎上,還可以使用Spark的其他子框架,如叢集學習、圖計算等,對流資料進行處理。

2.4 特性分析

吞吐量與延遲性

Spark目前在EC2上已能夠線性擴充套件到100個節點(每個節點4Core),可以以數秒的延遲處理6GB/s的資料量(60M records/s),其吞吐量也比流行的Storm高2~5倍,圖4是Berkeley利用WordCount和Grep兩個用例所做的測試,在 Grep這個測試中,Spark Streaming中的每個節點的吞吐量是670k records/s,而Storm是115k records/s。

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

Spark Streaming將流式計算分解成多個Spark Job,對於每一段資料的處理都會經過Spark DAG圖分解,以及Spark的任務集的排程過程,其最小的Batch Size的選取在0.5~2秒鐘之間(Storm目前最小的延遲是100ms左右),所以Spark Streaming能夠滿足除對實時性要求非常高(如高頻實時交易)之外的所有流式準實時計算場景。

exactly-once 語義

更加穩定的exactly-once語義支援。

反壓能力的支援

Spark Streaming 從v1.5開始引入反壓機制(back-pressure),通過動態控制資料接收速率來適配叢集資料處理能力.

Sparkstreaming如何反壓?

簡單來說,反壓機制需要調節系統接受資料速率或處理資料速率,然而系統處理資料的速率是沒法簡單的調節。因此,只能估計當前系統處理資料的速率,調節系統接受資料的速率來與之相匹配。

Flink如何反壓?

嚴格來說,Flink無需進行反壓,因為系統接收資料的速率和處理資料的速率是自然匹配的。系統接收資料的前提是接收資料的Task必須有空閒可用的Buffer,該資料被繼續處理的前提是下游Task也有空閒可用的Buffer。因此,不存在系統接受了過多的資料,導致超過了系統處理的能力。

由此看出,Spark的micro-batch模型導致了它需要單獨引入反壓機制。

反壓與高負載

反壓通常產生於這樣的場景:短時負載高峰導致系統接收資料的速率遠高於它處理資料的速率。

但是,系統能夠承受多高的負載是系統資料處理能力決定的,反壓機制並不是提高系統處理資料的能力,而是系統所面臨負載高於承受能力時如何調節系統接收資料的速率。

容錯

Driver和executor採用預寫日誌(WAL)方式去儲存狀態,同時結合RDD本身的血統的容錯機制。

API 和 類庫

Spark 2.0中引入了結構化資料流,統一了SQL和Streaming的API,採用DataFrame作為統一入口,能夠像編寫普通Batch程式或者直接像操作SQL一樣操作Streaming,易於程式設計。

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

廣泛整合

除了可以讀取HDFS, Flume, Kafka, Twitter andZeroMQ資料來源以外,我們自己也可以定義資料來源,支援執行在Yarn,Standalone及EC2上,能夠通過Zookeeper,HDFS保證高可用性,處理結果可以直接寫到HDFS

部署性

依賴java環境,只要應用能夠載入到spark相關的jar包即可。

3.Storm架構及特性分析

3.1 基本架構

Storm叢集採用主從架構方式,主節點是Nimbus,從節點是Supervisor,有關排程相關的資訊儲存到ZooKeeper叢集中。架構如下:

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

Nimbus

Storm叢集的Master節點,負責分發使用者程式碼,指派給具體的Supervisor節點上的Worker節點,去執行Topology對應的元件(Spout/Bolt)的Task。

Supervisor

Storm叢集的從節點,負責管理執行在Supervisor節點上的每一個Worker程式的啟動和終止。通過Storm的配置檔案中的supervisor.slots.ports配置項,可以指定在一個Supervisor上最大允許多少個Slot,每個Slot通過埠號來唯一標識,一個埠號對應一個Worker程式(如果該Worker程式被啟動)。

ZooKeeper

用來協調Nimbus和Supervisor,如果Supervisor因故障出現問題而無法執行Topology,Nimbus會第一時間感知到,並重新分配Topology到其它可用的Supervisor上執行。

執行架構

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

執行流程

1)戶端提交拓撲到nimbus。

2) Nimbus針對該拓撲建立本地的目錄根據topology的配置計算task,分配task,在zookeeper上建立assignments節點儲存task和supervisor機器節點中woker的對應關係;

在zookeeper上建立taskbeats節點來監控task的心跳;啟動topology。

3) Supervisor去zookeeper上獲取分配的tasks,啟動多個woker進行,每個woker生成task,一個task一個執行緒;根據topology資訊初始化建立task之間的連線;Task和Task之間是通過zeroMQ管理的;後整個拓撲執行起來。

3.2 基於Yarn層面的架構

Apache 流框架 Flink,Spark Streaming,Storm對比分析(2)

在YARN上開發一個應用程式,通常只需要開發兩個元件,分別是客戶端和ApplicationMaster,其中客戶端主要作用是提交應用程式到YARN上,並和YARN和ApplicationMaster進行互動,完成使用者傳送的一些指令;而ApplicationMaster則負責向YARN申請資源,並與NodeManager通訊,啟動任務。

不修改任何Storm原始碼即可將其執行在YARN之上,最簡單的實現方法是將Storm的各個服務元件(包括Nimbus和Supervisor)作為單獨的任務執行在YARN上,而Zookeeper作為一個公共的服務執行在YARN叢集之外的幾個節點上。

1)通過YARN-Storm Client將Storm Application提交到YARN的RM上;

2)RM為YARN-Storm ApplicationMaster申請資源,並將其執行在一個節點上(Nimbus);

3)YARN-Storm ApplicationMaster 在自己內部啟動Nimbus和UI服務;

4)YARN-Storm ApplicationMaster 根據使用者配置向RM申請資源,並在申請到的Container中啟動Supervisor服務;

5)與向普通Storm叢集提交Topology一樣,使用者直接與執行在Nimbus互動,提交Topology。

3.3元件棧

3.4 特性分析

簡單的程式設計模型。

類似於MapReduce降低了並行批處理複雜性,Storm降低了進行實時處理的複雜性。

服務化

一個服務框架,支援熱部署,即時上線或下線App.

可以使用各種程式語言

你可以在Storm之上使用各種程式語言。預設支援Clojure、Java、Ruby和Python。要增加對其他語言的支援,只需實現一個簡單的Storm通訊協議即可。

容錯性

Storm會管理工作程式和節點的故障。

水平擴充套件

計算是在多個執行緒、程式和伺服器之間並行進行的。

可靠的訊息處理

Storm保證每個訊息至少能得到一次完整處理。任務失敗時,它會負責從訊息源重試訊息。

快速

系統的設計保證了訊息能得到快速的處理,使用ZeroMQ作為其底層訊息佇列。

本地模式

Storm有一個“本地模式”,可以在處理過程中完全模擬Storm叢集。這讓你可以快速進行開發和單元測試。

部署性

依賴於Zookeeper進行任務狀態的維護,必須首先部署Zookeeper。

4.三種框架的對比分析

Apache

Flink

SparkStreaming

Storm

架構

架構介於spark和storm之間,主從結構與spark streaming相似,DataFlow Grpah與Storm相似,資料流可以被表示為一個有向圖。 每個頂點是一個使用者定義的運算,每向邊表示資料的流動。

Native

架構依賴spark,主從模式,每個Batch處理都依賴主(driver),可以理解為時間維度上的spark DAG。

Micro-Batch

主從模式,且依賴ZK,處理過程中對主的依賴不大。

Native

容錯

基於Chandy-Lamport distributed snapshots checkpoint機制

Medium

WAL及RDD 血統機制

High

Records ACK

Medium

處理模型與延遲

單條事件處理

亞秒級低延遲

一個事件視窗內的所有事件。

秒級高延遲

每次傳入的一個事件

亞秒級低延遲

吞吐量

High

High

Low

資料處理保證

exactly once

High

exactly once(實現採用Chandy-Lamport 演算法,即marker-checkpoint )

High

at least once(實現採用record-level acknowledgments),Trident可以支援storm 提供exactly once語義。

Medium

高階API

Flink 棧中提供了提供了很多具有高階 API 和滿足不同場景的類庫:機器學習、圖分析、關係式資料處理

High

能夠很容易的對接Spark生態棧裡面的元件,同時能夠對接主流的訊息傳輸元件及儲存系統。

High

應用需要按照特定的storm定義的規則編寫。

Low

易用性

支援SQL Steaming,Batch和STREAMING採用統一程式設計框架

High

支援SQL Steaming

Batch和STREAMING採用統一程式設計框架。

High

不支援SQL Steaming

Low

成熟性

新興專案,處於發展階段。

Low

已經發展一段時間

Medium

相對較早的流系統,比較穩定。

High

社群活躍度

212 contributor,活躍度呈上升趨勢。

Medium

937 contirbutor

High

216 contributors,活躍度比較穩定。

Medium

部署性

部署相對簡單,只依賴JRE環境

Low

部署相對簡單,只依賴JRE環境

Low

依賴JRE環境和Zookeeper

High

對比分析

如果對延遲要求不高的情況下,建議使用Spark Streaming,豐富的高階API,使用簡單,天然對接Spark生態棧中的其他元件,吞吐量大,部署簡單,UI介面也做的更加智慧,社群活躍度較高,有問題響應速度也是比較快的,比較適合做流式的ETL,而且Spark的發展勢頭也是有目共睹的,相信未來效能和功能將會更加完善。

如果對延遲性要求比較高的話,建議可以嘗試下Flink,Flink是目前發展比較火的一個流系統,採用原生的流處理系統,保證了低延遲性,在API和容錯上也是做的比較完善,使用起來相對來說也是比較簡單的,部署容易,而且發展勢頭也越來越好,相信後面社群問題的響應速度應該也是比較快的。

個人對Flink是比較看好的,因為原生的流處理理念,在保證了低延遲的前提下,效能還是比較好的,且越來越易用,社群也在不斷髮展。

免費體驗雲安全(易盾)內容安全、驗證碼等服務

更多網易技術、產品、運營經驗分享請點選

相關文章:
【推薦】 關於Runtime.getRuntime().exec()產生阻塞的2個陷阱

相關文章