Spark缺點

無論是

Spark Streaming

還是

Structured Streaming

Spark

流處理的實時性還不夠,所以無法用在一些對實時性要求很高的流處理場景中。

這是因為

Spark

的流處理是基於所謂微批處理

( Micro- batch processing)

的思想,即它把流

處理看作是批處理的一種特殊形式,每次接收到一個時間間隔的資料才會去處理,所以天生很難在實時性上有所提升。

雖然在

Spark2.3

中提出了連續處理模型

( Continuous Processing Model),

但是現在只支援

很有限的功能,並不能在大的專案中使用。

Spark

還需要做出很大的努力才能改進現有的流處理模型想要在流處理的實時性上提升,就不能継續用微批處理的模式,而要想辦法實現真正的流處理即每當有一條資料輸入就立刻處理,不做等待。

Flink

採用了基於運算子

(Operator)

的連續流模型,可以做到

微秒級別的延遲

Flink 核心模型簡介

Flink

最核心的資料結構是

Stream

,它代表一個執行在多分割槽上的並行流。

Stream

上同樣可以進行各種轉換操作

(Transformation)

。與 Spark 的 RDD 不同的是,Stream 代表一個數據流而不是靜態資料的集合。所以,它包含的資料是隨著時間增長而變化的。而且 Stream 上的轉換操作都是逐條進行的,即每當有新的資料進來,整個流程都會被執行並更新結果。這樣的基本處理模式決定了 Flink 會比 Spark Streaming 有更低的流處理延遲性。

當一個 Flink 程式被執行的時候,它會被對映為 Streaming Dataflow,下圖就是一個Streaming Dataflow 的示意圖。

spark和flink對比

在圖中,你可以看出

Streaming Dataflow

包括

Stream

Operator

(運算子)。轉換運算子把一個或多個

Stream

轉換成多個

Stream

。每個

Dataflow

都有一個輸入資料來源(

Source

)和輸出資料來源(

Sink

)。與Spark的RDD轉換圖類似,Streaming Dataflow也會被組合成一個有向無環圖去執行。

Flink

中,程式天生是並行和分散式的。一個

Stream

可以包含多個分割槽(

Stream Partitions

),一個運算子可以被分成多個運算子子任務,每一個子任務是在不同的執行緒或者不同的機器節點中獨立執行的。如下圖所示:

spark和flink對比

從上圖你可以看出,

Stream

在運算子之間傳輸資料的形式有兩種:一對一和重新分佈。

一對一(

One-to-one)

Stream

維護著分割槽以及元素的順序,比如上圖從輸入資料來源到

map

間。這意味著map運算子的子任務處理的資料和輸入資料來源的子任務生產的元素的資料相同。你有沒有發現,它與RDD的窄依賴類似。

重新分佈(

Redistributing

):

Stream

中資料的分割槽會發生改變,比如上圖中

map

keyBy

之間。運算子的每一個子任務把資料傳送到不同的目標子任務。

Flink的架構

當前版本Flink的架構如下圖所示

spark和flink對比

這個架構和

Spark

架構比較類似,都分為四層:儲存層、部署層、核心處理引擎、

high-level

API

和庫。

從儲存層來看,

Flink

同樣相容多種主流檔案系統如

HDFS、Amazon S3

,多種資料庫如

HBase

和多種資料流如

Kafka

Flume

從部署層來看,

Flink

不僅支援本地執行,還能在獨立叢集或者在被

YARN

Mesos

管理的叢集上執行,也能部署在雲端。

核心處理引擎就是我們剛才提到的分散式

Streaming Dataflow

,所有的高階

API

及應用庫都會被翻譯成包含

Stream

Operator

Dataflow

來執行。

Flink

提供的兩個核心

API

就是

DataSet APl

DataStream APl

。你沒看錯,名字和

Spark

DataSet、DataFrame

非常相似。顧名思義,

DataSet

代表有界的資料集,而

DataStream

代表流資料。所以,

DataSet API

是用來做批處理的,而

DataStream API

是做流處理的。

也許你會問,Flink 這樣基於流的模型是怎樣支援批處理的?在內部,

DataSet

其實也用

Stream

表示,靜態的有界資料也可以被看作是特殊的流資料,而且

DataSet

DataStream

可以無縫切換。所以,

Flink

的核心是

DataStream

Flink 和 Spark 對比

透過前面的學習,我們瞭解到,

Spark

Flink

都支援批處理和流處理,接下來讓我們對這兩種流行的資料處理框架在各方面進行對比。首先,這兩個資料處理框架有很多相同點。

都基於記憶體計算;

都有統一的批處理和流處理

APl

,都支援類似

SQL

的程式設計介面;

都支援很多相同的轉換操作,程式設計都是用類似於

Scala Collection APl

的函數語言程式設計模式;

都有完善的錯誤恢復機制;

都支援

Exactly once

的語義一致性。

當然,它們的不同點也是相當明顯,我們可以從4個不同的角度來看。

從流處理的角度來講,

Spark

基於微批次處理,把流資料看成是一個個小的批處理資料塊分別處理,所以延遲性只能做到秒級。而

Flink

基於每個事件處理,每當有新的資料輸入都會立刻處理,是真正的流式計算,支援毫秒級計算。由於相同的原因,

Spark只支援基於時間的視窗操作(處理時間或者事件時間)

,而

Flink

支援的視窗操作則非常靈活,不僅支援時間視窗,還支援基於資料本身的視窗(另外還支援基於

time

count

session

,以及

data-driven

的視窗操作),開發者可以自由定義想要的視窗操作。

SQL

功能的角度來講,

Spark

Flink

分別提供

SparkSQL

Table APl

提供

SQL

互動支援。兩者相比較,

Spark

SQL

支援更好,相應的最佳化、擴充套件和效能更好,而Flink在SQL支援方面還有很大提升空間。

從迭代計算的角度來講,

Spark

對機器學習的支援很好,因為可以在記憶體中快取中間計算結果來加速機器學習演算法的執行。但是大部分機器學習演算法其實是一個有環的資料流,在

Spark

中,卻是用無環圖來表示。而

Flink

支援在執行時間中的有環資料流,從而可以更有效的對機器學習演算法進行運算。

從相應的生態系統角度來講,Spark 的社群無疑更加活躍。

Spark

可以說有著

Apache

旗下最多的開源貢獻者,而且有很多不同的庫來用在不同場景。而

Flink

由於較新,現階段的開源社群不如

Spark

活躍,各種庫的功能也不如

Spark

全面。但是

Flink

還在不斷髮展,各種功能也在逐漸完善。

如何選擇Spark和Flink

對於以下場景,你可以選擇

Spark

資料量非常大而且邏輯複雜的批資料處理,並且對計算效率有較高要求(比如用大資料分析來構建推薦系統進行個性化推薦、廣告定點投放等);

基於歷史資料的互動式查詢,要求響應較快(

impala,或者presto更優秀

);

基於實時資料流的資料處理,延遲性要求在在數百毫秒到數秒之間。

Spark

完美滿足這些場景的需求,而且它可以一站式解決這些問題,無需用別的資料處理平臺。由於

Flink

是為了提升流處理而建立的平臺,所以它適用於各種需要非常低延遲(微秒到毫秒級)的實時資料處理場景,比如實時日誌報表分析。

而且Flink 用流處理去模擬批處理的思想,比Spark 用批處理去模擬流處理的思想擴充套件性更好。