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

本文由網易雲 發布

本文內容接上一篇Apache 流框架 Flink,Spark Streaming,Storm對比分析(一)

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 任務沒有任何區別。

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數據通會不斷的把Block數據通過BlockManager或者WAL進行存儲,數據存儲之後ReceiverSupervisorlmpl會把存儲後的數據的元數據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服務;

3.3 組件棧

3.4 特性分析

簡單的編程模型。

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

服務化

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

可以使用各種編程語言

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

容錯性

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

水平擴展

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

可靠的消息處理

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

快速

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

本地模式

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

部署性

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

4.三種框架的對比分析

對比分析

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

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

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

網易有數:企業級大數據可視化分析平台。面向業務人員的自助式敏捷分析平台,採用PPT模式的報告製作,更加易學易用,具備強大的探索分析功能,真正幫助用戶洞察數據發現價值。可點擊這裡免費試用

了解 網易雲

網易雲官網:https://www.163yun.com/

新用戶大禮包:https://www.163yun.com/gift

網易雲社區:https://sq.163yun.com/


推薦閱讀:

Apache Kylin 深入Cube和查詢優化 提升Cube
Apache Kylin 優化利器KyBot: Rowkey一鍵優化
React 路/粉/黑 都該了解的 React license 爭議
Apache Pulsar的多租戶消息系統
如何看待2016年4月26日晚,中國互聯網被Struts2漏洞血洗?

TAG:Hadoop | Spark | Apache |