Flink Table Store 0.3 構建流式數倉最佳實踐

ApacheFlink發表於2023-03-08

摘要:本文整理自阿里巴巴高階技術專家,Apache Flink PMC 李勁松(之信),在 FFA 2022 實時湖倉的分享。本篇內容主要分為四個部分:

  1. 挑戰:Streaming DW 面臨的難題

  2. 案例:Flink+FTS 典型場景案例

  3. v0.3FTSV0.3 有什麼能力來幫助上述場景

  4. 總結:回顧和專案資訊




01

挑戰:Streaming DW 面臨的難題


Flink Table Store 0.3 構建流式數倉最佳實踐

首先,講一講 Streaming Data Warehouse 面臨的難題。Streaming Data Warehouse 是什麼呢?

如上圖所示,資料來源從 MySQL 或 Logs,透過 Flink CDC 或 Flink Streaming,把資料攝入到倉裡。這個倉可以分 ODS 層、DWD 層、DWS 層。每一層的儲存寫的是 Flink Table Store。

這樣一個看起來跟離線數倉相似的 Pipeline,它的特點是全鏈路實時流動。透過 Flink Streaming 作業串聯,在全鏈路流動的同時,資料沉澱到了 Flink Table Store 的儲存上。這個儲存不再是之前的 Kafka,只能留,不能查。

這個架構的典型特點是全鏈路實時可流動,全鏈路實時可查。這個儲存裡的資料,能被各生態的計算引擎查詢分析。沉澱資料之後,每一份資料在 ODS 層、DWD 層、DWS 層,可以分層複用,減少大量儲存和計算的浪費。

Flink Table Store 0.3 構建流式數倉最佳實踐

雖然這個架構理解起來非常的簡單,但卻不容易實現。我們來簡單分析一下,儲存在這個架構中的作用。儲存主要有三個作用:

1. 訊息佇列。因為全鏈路是流起來的,儲存本身要做一個訊息佇列,可流寫、可流讀,需要有一定的順序性。
2. 沉澱資料。沉澱的歷史資料需要要面向各生態計算引擎,做到可分析。沉澱資料之後,這部分資料應該被管理。

3. 儲存需要增強流計算,讓流計算變得更簡單,解決流計算的難題。

Flink Table Store 0.3 構建流式數倉最佳實踐

如上圖所示,儲存在這個架構裡發揮了多少作用,又有多少挑戰呢?

1. 全增量一體攝入。在一個流作業中,全量資料讀完之後,無縫切換到增量資料再讀,資料和流作業一起進入下一個環節。儲存在這裡遇到的挑戰是,既然有資料全增量一體攝入,說明資料量很大,資料亂序很嚴重。儲存能不能撐住?能不能用高吞吐來支撐全增量一體攝入?
2. 訊息佇列的流讀。儲存本身作為訊息佇列需要流寫、流讀,非常靈活。儲存能不能提供全增量一體的流讀?能不能指定 timestamp 從歷史開始讀增量?
3. Changelog 的流讀。圖中的第三部分,Flink 基於 State 的計算嚴格依賴 Changelog。如果 Changelog 錯誤,Flink 計算將出現各種各樣正確性的問題。當使用者輸入到儲存後,從儲存流讀的 log 是否準確?變更日誌是否完整?這些問題是非常關鍵。
4. 可流 Join 的儲存。目前,流計算中 Join 是非常頭疼的問題。不光是流計算本身在儲存和流計算結合,儲存本身也應該在流 Join 上發揮較大的作用。
5. 豐富生態的查詢。儲存跟計算不一樣,儲存要有比較好的生態。因為不能假設計算能解決一切問題,所以儲存需要被各種引擎查詢。它必須有一個較好的生態。

02

案例:Flink+FTS 典型場景案例


Flink Table Store 0.3 構建流式數倉最佳實踐

如上圖所示,在業務上這個案例是一個銷售大寬表。它的業務邏輯是上圖中的的四張表,我需要把訂單表、退貨表、顧客表和退貨原因表,打寬到一起,方便各種引擎查詢。

接著,增量資料寫到 Clickhouse 或 ElasticSeach 中。Trino + FTS 的查詢可以滿足不少場景,但是有些查詢的要求更高,它的依賴面向 OLAP 面向索引。

因此,四個多表連線到一起,打成大寬表,然後寫到一張表當中,並且增量資料寫到下游的引擎中。在流計算中,如何做到 realtime 的打寬?這是一個比較難的問題。

我們先來分析下此例子中的各個表,因為訂單表和退貨表是同主鍵的,它們都有訂單 ID,訂單表中也有顧客 ID,它可以和顧客表進行 Join,獲取一些維表資訊。其次,顧客表一直在變化,顧客可以修改自己的資訊。最後,退貨原因表是不可變的。因為退貨就原因,一般是不能被編輯的。

對於業務來說,有一個非常簡單的思路,就是把這四張表 Join 一下,然後寫到儲存當中。但是這種方法的代價非常高,儲存會成倍增加,成本非常高。

面對真實的業務,我們想讓業務實現更多的離線計算、離線 Pipeline 變的實時化。但業務切換到實時化後,實時計算的成本是離線計算的數十倍。

所以針對此案例,如何使用 Flink Table Store 呢?

Flink Table Store 0.3 構建流式數倉最佳實踐

我們首先建立 DWD 的大寬表。訂單 ID 是主鍵,有些欄位來自訂單表,有些欄位來自退貨表,還有一些欄位來自顧客表和退貨原因表。

透過定義,它宣告 merge-engine=partial-update,changelog-producer=full-compaction,剩下的兩個是相關的引數。

透過 Flink Table Store 的 partial-update 的能力,使得相同的兩張表同時寫到一個大寬表當中,更新各自的欄位,互不影響。而且因為配置了 changelog-producer,所以在 Compaction 時會產生正確的寬表日誌,下游的流讀可以讀到最新合併後的資料。

Flink Table Store 0.3 構建流式數倉最佳實踐

接下來,對於顧客表和退貨原因表,怎麼打寬?

退貨原因表有一個特點是,它的表條數較少,退貨表不可更改。所以它比較適合使用 Flink Table Store 作為 Lookup Join 表。進行 Lookup Join,Flink Table Store 會維護一些磁碟 cache。使用者不用擔心資料量太大,導致 OOM。

結合使用 Flink 1.16 Retry Lookup,保證退貨表一定能 Join 到 reason 表。即使 reason 表更新較慢,它也能保證 Join 上。透過 Flink Retry Lookup 的方式,成本比較低。

Flink Table Store 0.3 構建流式數倉最佳實踐

接下來,講一講顧客表。顧客表跟退貨表不一樣,顧客表的資料量較大,它需要驅動更新。結合 Flink Table Store,希望能提供一個新的思路。

顧客表和訂單表 Join,它只有訂單 ID 和顧客 ID 的對映關係,以及顧客表的其它欄位。顧客表沒有訂單表的主鍵。所以這裡的需求是,我們需要給顧客表拿到訂單表的主鍵,也就是訂單 ID。

我們可以啟動一個雙流 Join 來使得顧客表拿到訂單 ID,這個雙流 Join 的 State 儲存成本是 訂單 ID 和顧客 ID 的對映關係,以及顧客表的內容,我們可以認為這個 State 不太大,它的成本可控,畢竟它沒有儲存龐大的訂單表。

經過 Join 之後,這個顧客表就能拿到訂單 ID,可以進行上述基於 FTS 的 Partial Update。

Flink Table Store 0.3 構建流式數倉最佳實踐

完成上游四張表 Partial Update 的寫入之後,最後啟動 Compaction 作業,它會不斷地產生 Changelog。所以下游可以啟動流讀作業,來流讀這張大寬表,寫入下游 Clickhouse 和 ES 當中。除此之外,這張大寬表面向多引擎,可以進行 Ad-hoc 查詢,你可以使用 Hive、Spark、Flink 或者 Trino 來實時查詢。

為什麼要選擇 Flink Table Store 呢?因為 Flink Table Store 使用方便,能夠低成本實時打寬。

03

V0.3:FTSV0.3 有什麼能力

來幫助上述場景


Flink Table Store 0.3 構建流式數倉最佳實踐

即將釋出的 Flink Table Store 0.3,有哪些功能實現上述的場景?

第一個場景,全增量一體匯入。在早期版本中,從 MySQL 把所有資料 Bulk Load 到一張表中。然後,將定期的增量資料 Load 到數倉當中,進行定期的排程作業。

Flink Table Store 0.3 構建流式數倉最佳實踐

這個流程鏈路較複雜,維護成本比較高。由於全量增量點位較難以對齊,所以全增量一起匯入,後期不用維護。除此之外,需要儲存有較強的寫入、更新、刪除資料的能力,才能撐得住大資料流量。

Flink Table Store 0.3 大幅增強全量階段的寫入儲存,特別是寫入時使用的物件儲存,0.3 大幅增強吞吐能力,有比較好的吞吐性。

後續在 0.4 中,也將提供整庫同步和 Schema Evolution 同步,將更好的提高入湖的使用者體驗。

Flink Table Store 0.3 構建流式數倉最佳實踐

第二個場景訊息佇列的流讀。作為訊息佇列必須要好用,在不宣告 Kafka 的情況下,Flink Table Store 表的流讀,希望能做到 30 秒到 1 分鐘的延遲,跟訊息佇列的順序一致。並且 Flink Table Store 也支援多種啊讀取模式。比如全增量一起的流讀,每次讀都能看到所有的資料。

除此之外,你可以透過 from-snapshot,從指定 snapshot-id 開始讀增量。你也可以透過 from-timestamp,從指定時間開始讀增量。你還可以指定 Latest,從最新資料,讀增量。Flink Table Store 的訊息佇列跟 Kafka 完全對齊。

Flink Table Store 0.3 構建流式數倉最佳實踐

第三個場景,變更日誌流讀。

舉個例子,如上圖所示,當你宣告主鍵之後:

1. 插入一條資料,主鍵為 1,column_1 為 1.0.
2. 再次插入了一條資料,主鍵仍為 1,column_1 為 2.0.
3. 此時,對流作業進行流讀,SUM 的結果應該是 3.0 還是 2.0?
簡單的計算,SUM 的結果就是 3.0,因為出現過兩條資料,所以加起來就是 3.0。但是,這兩條資料是相同的主鍵,它在更新時應該產生撤回,正確答案應該是 2.0。

Flink Table Store 提供多種 Changelog Producer 模式:

1. 比如 None,儲存不產生 Changelog,交給 Flink SQL 產生。Flink SQL 流讀的下游會產生一個相關節點,讓下游流作業使用 Changelog Normalize 節點。這個節點的 Cost 比較大。
2. 比如 Input,當 input 來自資料庫 CDC 的輸入,如果可以無條件信任 input,你可以選擇 Input,來自資料庫的 CDC 資料可以保證流讀到正確的 Changelog。
3. 在 Flink Table Store 0.3 中,提供了 Full-Compaction,隨著 Full-Compaction 產生完全正確的 Changelog,對流作業的正確性,各種模式的支援非常有用,但是你需要平衡 Full-Compaction 的成本和多久進行一次 Full-Compaction 的時延。

Flink Table Store 0.3 構建流式數倉最佳實踐

第四個場景,流連線。儲存對流式數倉到底起什麼作用?我們主要規定了三個作用,即訊息佇列、臨時資料可查、生態好。在 Flink Table Store 0.3,繼續加強了生態。當前,流面對的挑戰仍有很多,最大的挑戰是 Join。典型的 Join 有四種模式可以支援。

第一個模式,雙流 Join。假設拿到兩個 CDC 的流,按照 Flink SQL 寫法,Join 的結果就可以往下寫了。此時,Join 要處理兩條流,在 Streaming Join 中需要物化,在 State 中儲存兩個流物化的所有資料。假設 MySQL 中分庫分表有 1000 萬條,Streaming 中就要儲存 1000 萬條,而且如果有多個 Join,資料將會被重複的儲存,造成大量的成本。

雙流 Join 的好處是,Join 的語義非常正確,有保證,任何更新都能正確處理。但它缺點是,成本和效能有比較大的挑戰,其成本非常高。

第二個模式,Lookup Join。假設定義一張叫表叫主流,主流過來需要 Join 補欄位。此時,可以把維表當做映象表,在維表資料來的時候,不斷 Lookup 維表資料。Lookup Join 的好處是效能非常好,主表不會亂序,但無法解決維表的更新問題。

Flink Table Store 0.3 構建流式數倉最佳實踐

第三個模式,Partial Update。它可以幫助 Streaming 來做 Join 能力。Partial Up date 的本質是儲存本身,具有透過元件來更新部分列的能力。如果兩張表都有相同主鍵,它們可以分別進行 Partial Update。它的好處是效能非常好,給儲存很多空間來最佳化效能。效能較好,成本較低。但它的缺點是需要有同主鍵。

第四個模式,Indexed Partial Update。它可以使用 Flink 補齊主鍵,只需要拿到該主鍵件和主表主鍵間的對映關係即可。其次,由於維表的資料量比主表資料量要小很多,所以成本可控。透過使用 Flink 補齊主鍵之後,以較小 State 解決多流 Join 的問題。

綜上所述,我們希望提供儘可能多的 Join 模式,讓大家根據自己的業務來選擇需要的模式。

04

總結:回顧和專案資訊


Flink Table Store 0.3 構建流式數倉最佳實踐

第一部分,我們分析目前 Streaming Data Warehouse 的問題。它的主要挑戰是架構,我們在逐步解決;
第二部分,我們描述 Flink Table Store V0.3 核心解決的場景;
第三部分,我們將了講 Flink Table Store V0.3 哪些功能能幫助上述案例;
第四部分,Flink Table Store 會繼續加強 Streaming Data Warehouse,來解決更多問題。

如果有需求和問題,請聯絡我們!


Flink Table Store 0.3 構建流式數倉最佳實踐


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2938400/,如需轉載,請註明出處,否則將追究法律責任。

相關文章