1. 程式人生 > >基於Kafka的實時計算引擎如何選擇?Flink or Spark?

基於Kafka的實時計算引擎如何選擇?Flink or Spark?

1.前言

目前實時計算的業務場景越來越多,實時計算引擎技術及生態也越來越成熟。以Flink和Spark為首的實時計算引擎,成為實時計算場景的重點考慮物件。那麼,今天就來聊一聊基於Kafka的實時計算引擎如何選擇?Flink or Spark?

2.為何需要實時計算?

根據IBM的統計報告顯示,過去兩年內,當今世界上90%的資料產生源於新裝置、感測器以及技術的出現,資料增長率也會為此加速。而從技術上將,這意味著大資料領域,處理這些資料將變得更加複雜和具有挑戰性。例如移動應用廣告、欺詐檢測、計程車預訂、患者監控等場景處理時,需要對實時資料進行實時處理,以便做出快速可行的決策。

目前業界有開源不少實時計算引擎,以Apache基金會的兩款開源實時計算引擎最受歡迎,它們分別是Apache Flink和Apache Spark。接下來,我們來聊一聊它們的使用場景、優勢、侷限性、相似性、以及差異性。方便大家在做技術選型時,選擇切合專案場景的實時計算引擎。 

2.1 如何理解流式與實時?

說起實時計算,可能會說到流式計算,那麼流式和實時是否是等價的呢?嚴格意義上講,它們沒有必然的聯絡。實時計算代表的是處理資料耗時情況,而流式計算代表的是處理資料的一種方式。

2.2 什麼是流式處理?

首先,它是一種資料處理引擎,其設計時考慮了無邊界的資料集。其次,它與批處理不同,批處理的Job與資料的起點和終點有關係,並且Job在處理完有限資料後結束,而流式處理用於處理連續數天、數月、數年、或是永久實時的無界資料。

流處理的特點:

  • 容錯性:如果節點出現故障,流式處理系統應該能夠恢復,並且應該從它離開的位置再次開始處理;
  • 狀態管理:在有狀態處理要求的情況下,流式處理系統應該能夠提供一些機制來儲存和更新狀態資訊;
  • 效能:延時應儘可能的小,吞吐量應儘可能的大;
  • 高階功能:事件時間處理,視窗等功能,這些均是流式處理在處理複雜需求時所需要的功能;

2.3 什麼時候適合流式處理?

流式處理可以分析連續的資料流,在這種方式中,資料被視為連續流,處理引擎在很短的時間內(幾毫米到幾分鐘)內取數、分析、以及響應。下面讓我們來看看流式處理的場景使用場景:

  • 異常檢測:流式處理可以應用於連續的資料流並近乎實時的檢測異常。例如,在金融交易資料中,欺詐性交易可以被視為異常,流式處理可以檢測到這些,保護銀行和客戶免受財務損失。
  • 業務流程監控:業務流程涉及特定域中的多個事件。例如,在電子商務業務中,從下單、支付、出庫、送貨、再到使用者簽收的所有事件都可以被視為一個業務流程。流處理可用於監控此類流程的異常情況,例如在時間範圍內為完成、交付商品時出錯等。
  • 告警:流式處理可用於根據指定規則觸發告警,滿足特定條件,可以實時將告警傳送到不同的目標。

3. Spark

Spark已成為批處理中Hadoop的真正繼承者,也是第一個完美支援Lambda架構的框架。Spark受歡迎度極高,成熟並且廣泛使用。Spark免費提供Spark Streaming,它使用微批處理進行流式傳輸。在Spark2.0之後,添加了許多優秀的功能(例如對tungsten、watermarks、event time處理的支援),同時結構化流也更加抽象,截止本篇部落格Spark釋出的可用版本為2.4.3,可以在最新版本中在微批處理和連續流模式之間進行切換。

3.1 微批處理 & 連續流處理

結構化流式傳輸預設採用微批處理執行,Spark流式計算引擎會定時檢查流資料。在連續流處理中,Spark不會啟動定時任務,而是啟動一組長時間執行的任務,這些任務可以連續讀取、處理、寫入資料。

微批處理中,驅動程式通過將記錄Offset儲存到預寫Log來檢測進度,然後可以使用該Log重新進行查詢。需要注意的是,在微批處理處理開始之前,需要在下一個微批處理中處理的範圍Offset儲存到Log中,以便獲取確定性的重新執行和端到端語義。因此,源記錄可能需要等待當前的微批處理處理完成,然後記錄其Offset。

連續流處理中,通過完善和改進演算法來檢測查詢進度,特殊標記的記錄被寫入到每個任務的輸入資料流中。當任務遇到標記時,任務會非同步報告處理的最後一個Offset,一旦驅動程式收到寫入接收器的所有任務的Offset,它就會將它們寫入預寫Log中。由於Checkpoint完全非同步,因此任務可以不間斷的繼續,並提供一致的毫秒級延時。

 3.2 Streaming 

對於Spark Streaming來說,當不同的資料來源輸入進來時,基於固定的時間間隔,會形成一系列固定不變的資料集或者事件集(例如Kafka、Flume等)。這正好和Spark RDD基於固定的資料集吻合,從每一個批處理來看,空間維度的RDD依賴關係一致,不同的是這4個批處理輸入的資料規模和資料內容不同,所以生成的RDD依賴關係例項不一樣。

3.3 優勢

列舉了Spark常見優勢,如下所示:

  • 支援Lambda,且在Spark中免費使用
  • 高吞吐量,適用於不需要子延時的用例
  • 容錯性,預設使用微批處理
  • 高度抽象的API
  • 社群活躍度高
  • 支援Exactly Once

3.4 限制

另外,Spark也有它不足的地方,如下所示:

  • 不是真正意義上的實時計算,不能夠滿足低延時需求
  • 需要調整的引數太多,很難做到全面
  • 在許多高階功能中落後於Flink

4.Flink

Flink也是來自Spark類似的學術背景,Spark來自加州大學伯克利分校,Flink來自柏林大學。像Spark一樣,它也支援Lambda,但實現與Spark完全相反。Flink本質上是一個真正的實時計算引擎,將批處理作為有限資料流的特殊情況。雖然兩個計算框架中的API相似,但它們在實現中沒有任何相似之處,在Flink中,Map、Filter、Reduce等各個函式實現為長時間執行的運算子(類似於Storm中的Bolt)。

4.1 什麼是Apache Flink?

Flink是一個開源的實時計算引擎,是實時計算領域的領導者。它擁有出色的圖計算和機器學習功能,其底層支援On YARN模式,且提供了本地&分散式模式,以及Docker&Kubernetes等容器部署。

4.2 如何使用Flink解決問題?

在低延時場景,需要實時資料,以便能夠更快的檢測和解決關鍵事件。例如,在使用Flink之前,計算的基本業務指標,實現的延時時間約為3到4小時,這意味著,如果工程師在早上10點左右檢測到業務指標變化異常,只能在下午14點左右開始排查。如果能夠立馬解決,則只能在下午18左右時來驗證解決方案,這樣實現起來效率不是很高。

假如你的業務資料是基於時間序列的,那麼我們需要使用事件時間來處理在時間視窗內對業務指標進行分組。同時,Flink也可以很輕鬆的與儲存在Kafka和HDFS中的業務資料進行整合。另外,Flink具有良好的非功能特性,便於在生產中執行,易於與不同的監控後端整合(例如Graphite、Prometheus等),以及提供良好的UI介面。此外,Flink工作的快速開發週期以及簡單的執行模型使得學習曲線平穩,開發效率高。

4.3 什麼是視窗和事件時間?

Flink相比較Spark Streaming不僅提供了更低的延時,而且Flink還對視窗和事件時間提供了更好的支援。

4.3.1 視窗

現實場景中,大部分的資料來源都是無界的,很多情況下,我們會對固定時間間隔的資料進行統計,比如每隔10秒統計一下叢集服務的QPS,此時,視窗機制能夠很好的幫助我們實現這類需求。

  1. 情況一:假設資料來源分別在時間14秒,第14秒和第16秒產生訊息型別K的訊息(視窗大小為10秒)。這些訊息將落入視窗中,如上圖所示,在第14秒產生的前兩個訊息將落入視窗1(5秒~15秒)和視窗2(10秒~20秒),第16秒產生的第三個訊息將落入視窗2(10秒~10秒)和視窗3(15秒~25秒)。每個視窗發出的最終計數分別為(F,2)、(F,3)、(F,1),這是一種理想的狀態。
  2. 情況二:假設其中一條訊息(第14秒生產的)由於網路原因到達時延時了5秒(第19秒到達),那麼此時訊息在視窗的分佈如何呢?延時的訊息落入到視窗2和視窗3,因為第19秒在10秒~20秒和15秒~25秒這兩個視窗。對於視窗2來說,計算沒有什麼問題(因為訊息應該落入該視窗),但是它影響了視窗1和視窗3的結果。

4.3.2 事件時間

現在我們嘗試使用事件時間來解決情況二的延時問題。要啟用事件時間處理,需要一個時間戳提取器,從訊息中提取事件時間資訊。流式計算按照資料的事件時間來將資料分配到對應的視窗,而不是按照處理資料的時間,處理結果如下圖。

引入事件時間後的結果看起來更好了,視窗2和視窗3發出了正確的結果,但是視窗1仍然是錯誤的。Flink沒有將延遲的訊息分配給視窗3,因為它現在檢查的是訊息的事件時間了,並且理解它不在視窗中。但是為什麼沒有將訊息分配給視窗1呢?原因在於延遲的訊息到達系統時(第19秒),視窗1的評估已經完成了(15秒)。

4.3.3 水印

為了達到解決情況二的問題,達到情況一的預期結果。引入水印機制,水印機制可以看作是一種告訴Flink一個訊息延遲多少的方式。現在將水印設定為當前時間負5秒,告訴Flink希望訊息最多有5秒的延遲,這是因為每個視窗在水印通過時被評估。由於設定的水印時間為當前時間負5秒,所以視窗1(5秒~15秒)將在第20秒時被評估,以此類推,視窗2(10秒~20秒)將在第25秒時進行評估。優化後的結果如下:

最後調整引入水印機制後,得到正確的結果,這3個視窗均按照預期的方式發出計數,即(F,2)、(F,3)、(F,1)。

5.總結(Flink VS Spark)

瞭解了Flink和Spark各自的特點後,知道了Spark Streaming通過小批量的方式保證了吞吐的情況下,同時提供了Exactly Once語義,但是不是嚴格意義上的實時,而且由於微批處理的方式,對視窗和事件時間的支援比較有限。Flink採用分散式快照的方式實現了一個高吞吐、低延時,並且支援Exactly Once的實時計算引擎,同時Flink的實時計算引擎也能更好支援視窗和事件時間。

通過對Flink和Spark特點的掌握,再結合實際的專案需求、業務場景、以及技術儲備,來選取最適合的計算引擎。

6.結束語

這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!

另外,博主出書了《Kafka並不難學》和《Hadoop大資料探勘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那裡點選購買連結購買博主的書進行學習,在此感謝大家的支援。關注下面公眾號,根據提示,可免費獲取書籍的教學視