Flink不止於計算,存算一體才是未來

瘋碼牛Pro發表於2022-03-25

伴隨著實時化浪潮的發展和深化,Flink 已逐步演進為實時流處理的領軍技術和事實標準。Flink 一方面持續優化其流計算核心能力,不斷提高整個行業的流計算處理標準,另一方面沿著流批一體的思路逐步推進架構改造和應用場景落地,但是,隨著計算流批統一的逐漸完善的同時,Flink儲存的流批統一缺陷顯得尤為捉襟見肘

Flink 這幾年一直在反覆強調流批一體,即:使用同一套 API、同一套開發正規化來實現大資料的流計算和批計算,進而保證處理過程與結果的一致性。

但是,之前Flink一直強調的僅僅是計算層的流批一體,至於流批一體,還有哪些層面呢?

  • 資料整合流批一體:離線與實時是否使用統一資料採集方式;如統一通過 CDC 或者 OGG 將資料實時捕獲推送到 kafka,批與流在從 kafka 中消費資料,載入明細層。

  • 資料儲存流批一體:離線與實時資料是否統一分層、統一儲存;相容資料的一致性和實時性。

  • 處理邏輯流批一體:流與批處理是否使用統一 SQL 語法或者 ETL 元件,再通過底層分別適配流與批計算引擎,保證資料口徑的一致性。

  • 計算引擎流批一體:流與批使用同一套計算引擎,從根本上避免同一個處理邏輯流批兩套程式碼問題。

其實,在解決了計算層的問題之後,掣肘的便是資料儲存。目前,很多實時數倉中,實時鏈路採用kafka之類的訊息佇列,但是中間訊息佇列資料不利於分析。如果使用者想要分析實時鏈路中一個明細層的資料,其實非常不方便,很多使用者目前採用的辦法可能是先把這個明細層中的資料匯出來,比如導到 Hive 做離線分析,但這個時效性會大幅下降,或者為了加速查詢,把資料匯入到其他 OLAP 引擎中,但這又會增加系統複雜度,且資料一致性同樣很難保證。

截止到目前,整個行業還沒有完整的一站式解決計算引擎和資料儲存流批一體的技術方案,這對當前流式計算引擎提出了更高的要求和挑戰,不過慶幸的是,flink已經在這方面佈局,在下一個迭代版本flink1.5中,被定義為流批一體的資料儲存系統的Flink Dynamic Table即將面世。

毫無疑問,這對整個行業是巨大的創新。

提到flink發展儲存系統,我們不得不先回顧傳統大資料架構的演化過程,以史為鏡,才能發現儲存計算的一體的重要性和緊迫性

一 迭代中的資料倉儲,磕磕絆絆

實時數倉的架構,從經典的主題建模,到維度建模,再到hadoop體系,後面的lamda架構,kappa架構,在逐步完善,但一直沒有形成完整的解決方案。

1)離線數倉

Flink不止於計算,存算一體才是未來

使用hadoop平臺的hive做資料倉儲,報表層資料儲存在mysql中,使用tableau做報表系統,這樣不用擔心儲存問題、計算速度也大大加快了。在此基礎上,提供hue給各個部門使用,這樣簡單的取數工作可以由運營自己來操作,使用presto可以做mysql、hive的跨庫查詢,大大提升了查詢效率。

2)Lambda架構

Flink不止於計算,存算一體才是未來

為了計算一些實時指標,就在原來離線數倉的基礎上增加了一個實時計算的鏈路,並對資料來源做流式改造(即把資料傳送到訊息佇列),實時計算去訂閱訊息佇列,直接完成指標增量的計算,推送到下游的資料服務中去,由資料服務層完成離線&實時結果的合併

需要注意的是流處理計算的指標批處理依然計算,最終以批處理為準,即每次批處理計算後會覆蓋流處理的結果(這僅僅是流處理引擎不完善做的折中)。

Lambda架構整合離線計算和實時計算,融合不可變性(Immunability),讀寫分離和複雜性隔離等一系列架構原則,可整合Hadoop,Kafka,Storm,Spark,Hbase等各類大資料元件。

同樣的需求需要開發兩套一樣的程式碼,這是Lambda架構最大的問題,兩套程式碼不僅僅意味著開發困難(同樣的需求,一個在批處理引擎上實現,一個在流處理引擎上實現,還要分別構造資料測試保證兩者結果一致),後期維護更加困難,比如需求變更後需要分別更改兩套程式碼,獨立測試結果,且兩個作業需要同步上線。

資源佔用增多:同樣的邏輯計算兩次,整體資源佔用會增多(多出實時計算這部分)。

實時鏈路和離線鏈路計算結果容易讓人誤解,昨天看到的資料和今天看到的資料不一致**。

下游處理複雜,需要整合實時和離線處理結果,這一部分往往是我們在呈現給使用者之前就完成了的。

3)Kappa架構

Flink不止於計算,存算一體才是未來

 

再後來,實時的業務越來越多,事件化的資料來源也越來越多,實時處理從次要部分變成了主要部分,架構也做了相應調整,出現了以實時事件處理為核心的Kappa架構。當然這不要實現這一變化,還需要技術本身的革新——Flink,Flink 的出現使得Exactly-Once 和狀態計算成為可能,這個時候實時計算的結果保證最終結果的準確性。

Lambda架構雖然滿足了實時的需求,但帶來了更多的開發與運維工作,其架構背景是流處理引擎還不完善,流處理的結果只作為臨時的、近似的值提供參考。後來隨著Flink等流處理引擎的出現,流處理技術很成熟了,這時為了解決兩套程式碼的問題,LickedIn 的Jay Kreps提出了Kappa架構。

Kappa架構可以認為是Lambda架構的簡化版(只要移除lambda架構中的批處理部分即可)。在Kappa架構中,需求修改或歷史資料重新處理都通過上游重放完成。

存在的問題:Kappa架構最大的問題是流式重新處理歷史的吞吐能力會低於批處理,但這個可以通過增加計算資源來彌補。

4)混合架構

Flink不止於計算,存算一體才是未來

在真實的場景中,很多時候並不是完全規範的Lambda架構或Kappa架構,可以是兩者的混合,比如大部分實時指標使用Kappa架構完成計算,少量關鍵指標(比如金額相關)使用Lambda架構用批處理重新計算,增加一次校對過程

Kappa架構並不是中間結果完全不落地,現在很多大資料系統都需要支援機器學習(離線訓練),所以實時中間結果需要落地對應的儲存引擎供機器學習使用,另外有時候還需要對明細資料查詢,這種場景也需要把實時明細層寫出到對應的引擎中。

還有就是Kappa這種以實時為主的架構設計,除了增加了計算難度,對資源提出了更改的要求之外,還增加了開發的難度,所以才有了下面的混合架構,可以看出這個架構的出現,完全是出於需求和現狀考慮的。

混合架構在解決了部分業務問題的同時,也帶了架構的複雜性,在計算引擎及儲存介質上,存在多元性,那麼不管是學習成本還是開發成本以及後期的維護成本,都是指數級的增長,未必是一種最優的選擇。

同樣,混合架構支援實時入湖、入湖實時增量分析,但這些場景的實時性大打折扣,因為資料湖儲存格式本質還是 Mini-Batch,實時計算在混合架構中退化到 Mini-Batch 模式。毫無疑問,這對實時性要求很高的業務是很大的災難。

二 Flink流批一體的架構演進,帶來無限想象

Flink 流批一體在技術架構演進和落地應用兩方面都有了新進展。

技術演進層面,Flink 流批一體 API 和架構改造已經完成,在原先的流批一體 SQL 基礎上,進一步整合了 DataStream 和 DataSet 兩套 API,實現了完整的 Java 語義層面的流批一體 API,架構上做到了一套程式碼可同時承接流儲存與批儲存。

在2021年 10 月釋出的 Flink 1.14 版本中,已經可以支援在同一個應用中混合使用有界流和無界流:Flink 現在支援對部分執行、部分結束的應用(部分運算元已處理到有界輸入資料流的末端)做 Checkpoint。此外,Flink 在處理到有界資料流末端時會觸發最終 Checkpoint,以確保所有計算結果順利提交到 Sink。

而批執行模式現在支援在同一應用中混合使用 DataStream API 和 SQL/Table API(此前僅支援單獨使用 DataStream API 或 SQL/Table API)。

此外,Flink 更新了統一的 Source 和 Sink API,開始圍繞統一的 API 整合聯結器生態。新增的混合 Source 可在多個儲存系統間過渡,實現諸如先從 Amazon S3 中讀取舊的資料再無縫切換到 Apache Kafka 這樣的操作。

三 Flink CDC ,流批一體走向成熟的助推器

Flink不止於計算,存算一體才是未來

資料整合、不同資料來源之間的資料同步對於很多團隊來說是剛需,但傳統方案往往復雜度太高且時效性不好。傳統的資料整合方案通常是離線資料整合和實時資料整合分別採用兩套技術棧,其中涉及很多資料同步工具,比如 Sqoop、DataX 等,這些工具要麼只能做全量要麼只能做增量,開發者需要自己控制全增量的切換,配合起來比較複雜。

這個時候,flink cdc粉墨登場,對變更資料實時捕獲。基於 Flink 的流批一體能力和 Flink CDC,只需要寫一條 SQL,就可以做到先全量同步歷史資料,再自動斷點續傳增量資料,實現一站式資料整合。全程無需使用者判斷和干預,Flink 能自動完成批流之間的切換並保證資料的一致性。

Flink CDC Connectors 作為一個獨立的開源專案,從去年 7 月份開源以來,一直保持相當高速的發展,平均兩個月一個版本。目前 Flink CDC 版本已經更新到 2.1 版本,並完成了很多主流資料庫的適配,比如 MySQL、PostgreSQL、MongoDB、Oracle 等,更多資料庫如 TiDB、DB2 等的對接工作也在進行中。可以看到已經有越來越多企業在自己的業務場景中使用 Flink CDC。

四 Flink流式數倉,讓存算一體的不再是遠方

Flink 流批一體的理念可以在上述場景下得到充分應用。Flink 可以讓當前業界主流數倉架構再進階一層,實現真正端到端全鏈路的實時化分析能力,即:當資料在源頭髮生變化時就能捕捉到這一變化,並支援對它做逐層分析,讓所有資料實時流動起來,並且對所有流動中的資料都可以實時查詢。再借助 Flink 完備的流批一體能力,使用同一套 API 就可以同時支援靈活的離線分析。這樣一來,實時、離線以及互動式查詢分析、短查詢分析等,就可以統一成一整套解決方案,成為理想中的“流式數倉(Streaming Warehouse)”。

流式數倉(Streaming Warehouse)更準確地說,其實是“make data warehouse streaming”,就是讓整個數倉的資料全實時地流動起來,且是以純流的方式而不是微批(mini-batch)的方式流動。目標是實現一個具備端到端實時性的純流服務(Streaming Service),用一套 API 分析所有流動中的資料,當源頭資料發生變化,比如捕捉到線上服務的 Log 或資料庫的 Binlog 以後,就按照提前定義好的 Query 邏輯或資料處理邏輯,對資料進行分析,分析後的資料落到數倉的某一個分層,再從第一個分層向下一個分層流動,然後數倉所有分層會全部流動起來,最終流到一個線上系統裡,使用者可以看到整個數倉的全實時流動效果。

在這個過程中,資料是主動的,而查詢是被動的,分析由資料的變化來驅動。同時在垂直方向上,對每一個資料明細層,使用者都可以執行 Query 進行主動查詢,並且能實時獲得查詢結果。此外,它還能相容離線分析場景,API 依然是同一套,實現真正的一體化。

目前業界還沒有這樣一個端到端全流式鏈路的成熟解決方案,雖然有純流的方案和純互動式查詢的方案,但需要使用者自己把兩套方案加起來,必然會增加系統的複雜性,如果要再把離線數倉方案也加進來,系統複雜性問題就更大了。流式數倉要做的是在實現高時效性的同時,不進一步提高系統複雜性,讓整個架構對於開發和運維人員來說都是非常簡潔的。

當然,流式數倉是終態,要達成這個目標,Flink 需要一個配套的流批一體儲存支援。其實 Flink 本身有內建的分散式 RocksDB 作為 State 儲存,但這個儲存只能解決任務內部流資料狀態的儲存問題。

流式數倉需要一個計算任務之間的表儲存服務:第一個任務將資料寫進去,第二個任務就能從它實時地再讀出來,第三個任務還能對它執行使用者的 Query 分析。因此 Flink 需要再擴充套件出一個跟自身理念配套的儲存,從 State 儲存走出來,繼續向外走。為此,Flink 社群提出了新的 Dynamic Table Storage,即具備流表二象性的儲存方案。

Flink Dynamic Table可以理解為一套流批一體的儲存,並無縫對接 Flink SQL。原來 Flink 只能讀寫像 Kafka、HBase 這樣的外部表,現在用同一套 Flink SQL 語法就可以像原來建立源表和目標表一樣,建立一個 Dynamic Table。

流式數倉的分層資料可以全部放到 Flink Dynamic Table 中,通過 Flink SQL 就能實時地串聯起整個數倉的分層,既可以對 Dynamic Table 中不同明細層的資料做實時查詢和分析,也可以對不同分層做批量 ETL 處理

從資料結構上看,Dynamic Table 內部有兩個核心儲存元件,分別是 File Store 和 Log Store。顧名思義,Flie Store 儲存 Table 的檔案儲存形式,採用經典的 LSM 架構,支援流式的更新、刪除、增加等;同時,採用開放的列存結構,支援壓縮等優化;它對應 Flink SQL 的批模式,支援全量批式讀取。而 Log Store 儲存的是 Table 的操作記錄,是一個不可變更序列,對應 Flink SQL 的流模式,可以通過 Flink SQL 訂閱 Dynamic Table 的增量變化做實時分析,目前支援外掛化實現。

未來,利用 Flink CDC、Flink SQL、Flink Dynamic Table 就可以構建一套完整的流式數倉,實現實時離線一體化及對應計算儲存一體化的體驗。那便是大資料技術,flink技術發展的又一個精進高度。

相關文章