讀Flink原始碼談設計:流批一體的實現與現狀

泊浮目發表於2022-03-18

本文首發於泊浮目的語雀:https://www.yuque.com/17sing

版本日期備註
1.02022.3.16文章首發

0.背景:Dataflow之前

在Dataflow相關的論文發表前,大家都往往認為需要兩套API來實現流計算和批計算,典型的實現便是Lambda架構。

由於早期的流處理框架並不支援Exactly Once,導致流處理的資料並不精準。在這個基礎上,一旦資料出現問題,則要導致大量的資料重放——這是因為事件往往是有時序要求的。因此,Lambda往往會通過流處理框架獲取不是特別精準的結果,同時也會定時執行批處理程式,來獲取更精準的結果——當更精準的結果出來時,我們就不需要前者了。

但這也帶來的新的問題,所有的檢視都需要流、批處理層各做一次,程式碼也要寫兩套,這帶來了資料口徑不同。可以說是在計算機資源以及人力資源上至少加了兩倍的開銷。

Kappa提出了將所有資料落到Kafka上,將儲存模型與計算模型統一,但犧牲了時間——當資料量大時,回溯計算的壓力巨大。

直到The dataflow model: a practical approach to balancing correctness, latency, and cost in massive-scale, unbounded, out-of-order data processing發表後,流與批有望在程式設計模型上統一, 上述相關的問題得以緩解

1. Flink的實現

Flink比起其他的流處理框架,更優在兩點:

  1. 遵循Dataflow模型,在程式設計模型上統一流批一體
  2. 改進Chandy-Lamport演算法,以更低的代價保證精準一次的實現

1.1 程式設計模型統一的背後

程式設計模型的統一具體體現在Flink SQL以及DataStream上。我們可以用相同的SQL or 幾乎相同的程式碼跑流與批的任務。尤其是SQL,比起DataStream在宣告式上更甚。因此使用者在使用它們時,僅僅需要描述自己想要什麼,而不是自己要做什麼。具體做什麼的事,Flink框架會幫你搞定。

在Flink框架上,目前主要解決了以下問題:

  • IO模型:批處理會更加關注吞吐,因此是pull模型;而流處理更加關注實時性,因此是push模型。基於這個條件,Source運算元需要同時支援兩種模型來適應不同的計算模式。詳細見 FLIP-27: Refactor Source Interface
  • 排程策略:批處理的運算元並不需要同時線上,前一批的運算元完成後再排程後一批運算元即可——由於計算資源往往比儲存資源昂貴,這是一個很不錯的優化方案。當然在資源充足的情況下,追求效能也可以不考慮這種策略;但流處理的作業需要作業啟動時就全部被排程。因此,StreamGraph需要同時支援這兩種模式——即LazyScheduling和EagerScheduling。
  • 批流的銜接:假如我們要分析近30天的資料,大多數情況下都是29天的離線資料加上最近一天的實時資料,如何保證銜接時資料不多也不少,其實是個麻煩的事情,在不少工程實踐中會用一些比較hacks的方法。好在Flink1.4中引入了 Hybrid Source來簡化這件事—— FLIP-150: Introduce Hybrid Source

1.2 Checkpoint不是銀彈

Checkpoint是Flink框架中重要的容錯機制,它的一個前提要求是資料來源可重複讀。在數倉場景下,雖然絕大多數情況下資料都不會發生變化——但也會有冷資料處理機制以及一些merge發生。這將對資料可重讀造成一定的挑戰。另外,在筆者負責的產品QMatrix中,對資料庫做全量遷移時也會遇到類似的挑戰:T1時刻讀到的全量資料為集合1,而T2時刻讀到的全量資料則為集合2。而MVVC也只能維持在一個session中。

上面描述的是在資料來源要考慮的容錯條件。在資料已經全部流入任務時,容錯機制也需要重新考慮——儘量避免重複讀取資料來源以及上游任務的重算。因此社群引入了可插拔的Shuffle Service來提供Shuffle資料的持久用以支援細粒度的容錯恢復——FLIP-31: Pluggable Shuffle Service

2. 剩下的問題:資料來源不統一

上述流批銜接的前提是資料來源被分為了流資料來源和批資料來源。那麼口徑便是不統一的,這會帶來一些對接成本。

目前流行的方案會採用資料湖(如IceBerg、Hudi、DeltaLake)來做流批資料的統一,並且由於大多資料湖都支援Time Travel,離線資料的可重複讀問題也順帶解決。

另外,Pravega這種以流批一體儲存為設計目標的軟體可能也是解決方案之一。

3. 小結

在本文中,筆者和大家一起了解了流批一體的來源,以及Flink社群在流批一體中做出的努力。此外,我們也看到了有些問題並不是Flink這個框架可以解決的,需要整個大資料生態來一起演進,走向流批一體。

在文章的最後,感謝餘空同學的交流與指導,我們一起寫出了這篇文章。

相關文章