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

此文已由做者嶽猛受權網易雲社區發佈。
html

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

2.Spark Streaming架構及特性分析


2.1 基本架構

基因而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經 過操做變成中間結果保存在內存中。整個流式計算根據業務的需求能夠對中間的結果進行疊加,或者存儲到外部設備。數據庫

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

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層面的架構分析

上圖爲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。

具體實現

圖2.1 Spark Streaming程序轉換爲DStream Graph

圖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。

圖2.3時間維度生成RDD的DAG

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


代碼實現

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

2.3 組件棧

支持從多種數據源獲取數據,包括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。

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,易於編程。

普遍集成

除了能夠讀取HDFS, Flume, Kafka, Twitter andZeroMQ數據源之外,咱們本身也能夠定義數據源,支持運行在Yarn,Standalone及EC2上,可以經過Zookeeper,HDFS保證高可用性,處理結果能夠直接寫到HDFS

部署性

依賴java環境,只要應用可以加載到spark相關的jar包便可。

3.Storm架構及特性分析

3.1 基本架構


Storm集羣採用主從架構方式,主節點是Nimbus,從節點是Supervisor,有關調度相關的信息存儲到ZooKeeper集羣中。架構以下:

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上運行。

運行架構

運行流程

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層面的架構

在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個陷阱

相關文章
相關標籤/搜索