Fluss:面向實時分析設計的下一代流存儲

摘要:本文整理自阿里云智能 Flink SQL和數據通道負責人、Apache Flink PMC 伍翀(花名:云邪)老師,在 Flink Forward Asia 2024 主會場的分享。主要分享了一種專為流分析設計的新一代存儲解決方案——Fluss,并由阿里巴巴開源委員會副主席王峰先生,在 FFA 2024 現場進行了 Fluss 項目的開源。內容分為以下五個部分:

一、Kafka 在實時分析場景遇到的問題

二、Fluss:Flink Unified Streaming Storage

三、Fluss 核心特性

四、Fluss 未來規劃

五、Fluss 開源

當前業界呈現出一個顯著的趨勢,即大數據的處理正在從離線模式轉向實時化。我們可以觀察到,多個行業和應用場景都在進行實時化的演進。例如,互聯網、車聯網和金融等領域都正通過挖掘實時數據來提升業務價值。

在技術方面,大數據計算架構經歷了顯著的演變。從最初的 Hive 傳統數據倉庫,到引入 Lakehouse 湖倉架構,再到目前國內流行的 Paimon 流式湖倉架構,這些演進的核心驅動力在于提升業務的時效性。從傳統的 T+1 天模式,逐步縮短到 T+1 小時,再到 T+1 分鐘。然而,由于湖存儲架構是基于文件系統的,其分鐘級延遲幾乎是極限。但是許多業務場景,如搜索推薦、廣告歸因和異常檢測,都要求秒級的實時響應。因此,業界亟需能夠支持秒級存儲的解決方案。盡管大數據技術已經取得了長足的發展,但在大數據分析場景中,仍然缺乏一款能夠有效支持秒級存儲的解決方案。

那么在大數據里面最常用的秒級存儲是什么呢?當然是 Apache Kafka。Flink 與 Kafka 的組合也已經成為業界構建實時數倉的典型架構。然而,這個組合在實際應用中并不總是那么理想,原因在于當我們將 Kafka 應用于大數據分析時,會遇到一系列挑戰和問題。

Kafka 在實時分析場景遇到的問題

一個主要的問題是,Kafka 不支持數據更新功能。在數據倉庫中,“更新”是一個非常重要的功能,對于一個數倉來說,經常需要“更新”的能力去修正一些數據。由于 Kafka 不支持更新,所以它只能將主鍵上重復的數據都存儲下來。當計算引擎消費這些數據時,就會接收到重復的數據。

為了確保計算結果的準確性,計算引擎必須執行去重操作。然而,這個去重過程本身是非常耗費資源的。在 Flink 中,這需要使用 State 來物化上游的全部數據,并且每次消費 Kafka 數據時,都必須承擔去重的成本,這個成本是相當高的。這種高成本的去重要求限制了 Kafka 數據的業務復用能力。例如,在淘天集團構建實時數據中間層的過程中,由于 Kafka 的這些限制,他們選擇不構建 DWS 層。

第二個主要問題是,Kafka 不支持數據探查功能。在數據倉庫建設中,數據探查是一個基本能力。無論是排查問題還是進行數據探索,都需要進行數據查詢。然而,Kafka 本質上是一個黑盒,不支持直接查詢。為了解決這個問題,業界通常采用兩種方案:

  1. 同步到 OLAP 系統:將 Kafka 數據同步到 OLAP 系統中進行查詢。不過,這種方法會引入額外的系統組件,增加復雜性和成本。此外,數據在不同系統間的同步也可能導致不一致性。

  2. 使用 Trino 等查詢引擎直接查詢 Kafka:這種方法避免了數據同步問題,但由于 Kafka 僅支持 Full Scan,無法實現 Data Skipping,因此在處理大規模數據時效率較低。例如,在 1GB 數據上進行簡單查詢都可能需要一分鐘,這使得這種方法在大規模應用中基本上不可行。

第三個問題是數據回溯的困難。在數據倉庫中,數據回溯是常見需求,例如在物流行業中,可能需要回溯幾個月的數據進行分析。然而,在 Kafka 中,長時間存儲大量數據會導致成本過高,因此通常只能存儲幾天的數據。此外,當進行大規模數據回溯時,所有數據流量都必須經過 Kafka Broker,這會導致回溯操作的性能非常慢。同時,這種操作還會消耗 Broker 的 CPU 資源,污染其頁面緩存(page cache),從而對其他在線業務產生負面影響。

最后一個問題是網絡成本。根據多項數據資料顯示,網絡成本占據了 Kafka 成本的 88%。在數據倉庫中,一寫多讀是非常常見的操作模式,并且每個消費者通常只消費數據的一部分。例如,在阿里巴巴內部的數萬條 Flink SQL 作業中,平均每個作業僅使用了上游數據的 49% 的列。然而,當用戶需要消費這 49% 的列時,仍然需要讀取所有列的數據,這意味著需要承擔 100% 的網絡帶寬成本。這種情況導致了網絡資源的極大浪費。

總結來說,將 Kafka 用于實時分析場景時,會面臨以下核心問題:不支持更新、無法探查、數據回溯難、網絡成本高。這些問題導致 Flink + Kafka 的組合在某些實時分析應用場景中并不是最理想的選擇。

那么其本質的原因是什么?

這是因為Kafka 是為流消息設計的,并不是為流分析設計的。每個系統都有其特定的定位和優勢,Kafka 在消息隊列場景中非常高效,因為它通常以行存格式(如 CSV、JSON、AVRO)存儲數據。然而,對于需要處理大規模數據和復雜查詢的分析場景來說,行存格式的效率則顯得不足。需要底層存儲具備強大的Data Skipping 能力,以及支持列裁剪和條件下推等特性。在這種情況下,列存格式顯然更為適合。

Fluss:Flink Unified Streaming Storage

在構建這樣的四象限矩陣時,我們可以觀察到一個有趣的現象:象限左邊是業務型系統,右邊是分析型系統,上面是流存儲,下面是表存儲。可以看到,業務型系統里面不管是數據庫,還是流存儲,都采用的是行存,因為行存在這個場景更為高效。相反,像 Iceberg, Snowflake 這些分析型系統都采用的列存,因為列存在分析場景更高效。在這個矩陣中,右上角是一個空白區域,代表這個市場里空缺了一個存儲,即面向分析場景的流存儲,不出意料的話,這個流存儲采用的會是列存格式。

為了填補這一市場空白,并解決 Flink 在實時流分析場景中的痛點問題,我們在兩年前發起了一個流存儲項目,命名為 "FLink Unified Streaming Storage",取了項目名的首字母縮寫,拼成了 Fluss 這個單詞。值得一提的是,Flink 這個名字源自德語,意為“敏捷迅速”,而 Fluss 恰巧也是個德語單詞,意為“河流。這種命名不僅向 Flink 項目的起源致敬,也象征著流數據如同河流般源源不斷地流動、分發,并最終匯聚到數據湖中。

Fluss 核心特性

接下來介紹一下 Fluss 的一些核心特性:

首先,不出所料,Fluss 采用列式的流存儲。在底層文件存儲中采用了 IPC Streaming Format 協議,而 Arrow 是一種非常優秀的流式列存儲格式。基于 Arrow,我們實現了非常高效的列裁剪功能。右側展示了對 Fluss 和 Kafka 的基準測試結果。橫軸表示讀取列的數量,縱軸表示讀取吞吐量。可以看到,隨著裁剪的列數增加,Fluss 的讀取性能成比例上升。當裁剪到 90% 的列時,Fluss 的讀取吞吐量已經提高了 10 倍。此外,Fluss 的列裁剪是在服務端進行的,這意味著發送給客戶端的數據已經是裁剪過的,從而節省了大量的網絡成本。

第二點,實時更新和CDC是流分析中非常依賴的存儲能力,我們也對此進行了支持。可以理解為 Fluss 的流存儲基礎是一個日志表(Log Tablet),我們在日志之上構建了 KV 索引,從而支持高效的實時更新。Log 和 KV 之間的關系類似于流表的二象性,KV 的更新會生成變更日志(Changelog)寫入 Log Tablet;在故障恢復時,Log Tablet 的數據又用于恢復鍵值表(KV Tablet)。KV Tablet 底層實際上是一個 RocksDB 的 LSM 樹。因此,我們將流存儲與 LSM 結構結合,支持大規模實時更新以及部分列的更新,從而實現高效的寬表拼接。

此外,KV 生成的 Changelog 可以直接被 Flink 流讀取,無需額外的去重操作,節省了大量計算資源,實現了數據的業務復用。由于我們構建了 KV 索引,因此可以支持高性能的主鍵點查,并可作為實時處理鏈路中的維表關聯。用戶還可以通過點查的 query 語句直接探查 Fluss 數據,我們還支持 LIMIT、COUNT 等查詢功能,以滿足用戶的數據探查需求。

Fluss 還有一個非常重要的特性是湖流一體。過去,用戶為了搭建實時鏈路和離線鏈路,同樣一份數據需要在流存儲和湖存儲冗余存儲,造成成本浪費。湖流一體的概念是指“湖存儲的數據”和“流存儲的數據”能夠作為一個整體進行管理和消費,從而避免數據的冗余存儲,避免數據和元數據不一致的問題。

在底層,Fluss 維護了一個 Compaction Service,該服務會自動地將 Fluss 數據轉換為湖存儲的格式,并確保兩邊元數據的一致性。此外,它還保證兩邊的數據分布也是一致的,即分區和分區一一對齊,Bucket 和 Bucket 也一一對齊。這使得在流轉湖的過程中,無需引入網絡 Shuffle,只需將 Arrow 文件直接轉換為 Parquet 文件即可。這種轉換在業界已有非常成熟且高效的實現。

在擁有湖和流兩層數據后,Fluss 的一個關鍵特性是共享數據。具體來說,湖存儲作為流存儲的歷史數據層,負責存儲長周期、分鐘級延遲的數據;而流存儲作為湖存儲的實時數據層,負責存儲短周期、毫秒級延遲的數據,這兩者的數據可以互相共享。當進行流讀取時,湖存儲可以作為歷史數據提供高效的回溯性能。在回溯到當前位點后,系統會自動切換到流存儲繼續讀取,并確保不會讀取重復數據。在批查詢分析中,流存儲可以為 Lakehouse 提供實時數據的補充,從而實現 Lakehouse 秒級新鮮度的分析。我們將這種功能稱為 Union Read

除此之外,我們同步到湖存儲的格式完全遵循現有湖存儲的開放協議,因此現有的一些查詢引擎(如 Spark、StarRocks、Trino)可以直接查詢湖存儲中的數據,無縫融入用戶已有的 Lakehouse 架構中。目前,Fluss 已經完成了對 Paimon 的完全集成,對 Iceberg 的集成也在計劃中。

這就是我們Fluss整體的架構圖,Fluss是一個面向實時分析的流存儲。Fluss 需要維護一個 Server 集群,提供實時讀寫的能力,同時使用 Remote Storage 來做數據的分層,降低數據存儲成本。并且跟Lakchouse 做了一個非常無縫的集成來支持豐富的查詢能力。Fluss 的核心特性包括實時的流讀流寫、列式裁剪、流式的更新、CDC訂閱、實時點查、還有湖流一體。

Fluss 的核心特性結合,實現了一個非常理想的應用場景 Delta Join。在 Flink 中,雙流 Join 是一個非常基礎的功能,常用于構建寬表。然而,這也是一個常常讓開發人員感到頭疼的功能。因為雙流 Join 需要在 State 中維護上游全量的數據,這導致其狀態通常非常龐大。例如,淘寶最大的 Flink 作業之一是成交引導的雙流 Join(曝光關聯訂單),需要消耗 50TB 的狀態。但這帶來了很多問題,包括成本高、作業不穩定、Checkpoint超時、重啟恢復慢等等。

因此我們充分利用 Fluss 的 CDC 流讀+索引點查的能力研發了一套新的 Flink 的 Join 算子實現,叫 Delta Join。Delta Join 可以簡單理解成“雙邊驅動的維表Join”,就是左邊來了數據,就根據Join Key去點查右表;右邊來了數據,就根據 Join Key 去點查左表。全程就像維表Join一樣不需要state,但是實現了雙流Join一樣的語義,即任何一邊有數據更新,都會觸發對關聯結果的更新。

在測試中,我們使用了淘寶最大的雙流 Join 作業進行性能評估。在從雙流 Join 遷移到 Delta Join 后,成功減免了 50TB 的大狀態,使得作業運行更加穩定,Checkpoint 也不再超時。在雙十一的數據壓測回追中,我們發現,在保證相同吞吐量的情況下,Flink 的資源消耗能夠降低10倍,從2300 CU 減少到200 CU。此外,在回追過程中,我們還可以利用湖流一體歸檔的 Paimon 表加上 Flink Batch Join 進行數據回追,將回追1天數據的時間從4小時縮短到0.5小時。使用批作業進行數據回追,展示了流批一體的一個非常有前景的應用場景。

除了資源的減少和性能的提升,對于用戶最大的收益其實是靈活性的提升。以前的 State 是 Flink 內置的黑盒,用戶看不見摸不著,一修改作業就要重跑 State,耗時耗力。在使用 Delta Join 后,相當于狀態與作業進行了解耦,修改作業不需要重跑 State,所以回追很高效。并且數據都在 Fluss 里面,變得可查可分析,提升了業務靈活性和開發效率。目前,我們已經在 Flink 社區提交了 Delta Join 的 FLIP-486 提案,對于這個提案感興趣的朋友可以關注一下。

Fluss 未來規劃

關于 Fluss 的未來規劃,最重要的有三件事,這三件事分別對應了 Fluss 與三個開源軟件之間的關系:

  1. Kafka 協議兼容:這是為了幫助已有的流數據更好地遷移到 Fluss 上。

  2. 與 Flink 的深度協同優化:這一規劃包括通過存儲+優化器+執行引擎的協同優化,以解決之前存在的一些難點和痛點。Delta Join 就是一個很好的例子,通過這種深度協同,Fluss 可以與 Flink 緊密結合,提升整體的流處理性能和穩定性。

  3. 為 Paimon 提供實時數據層:通過打造湖流一體架構,Fluss 希望與 Paimon 結合,提供一個實時與離線一體化的存儲解決方案。

Fluss 開源

在11月29日舉辦的 Flink Forward Asia 2024 大會主題演講上,阿里巴巴正式開源了 Fluss 項目(https://github.com/alibaba/fluss)。阿里巴巴開源委員會副主席王峰先生,在現場進行了 Fluss 項目的開源,贏得了現場觀眾的熱烈反響。

Fluss 目前已經在 GitHub 上以 Apache 2.0 協議正式開源,項目地址為:https://github.com/alibaba/fluss,歡迎大家關注和 Star。并且我們計劃于 2025 年將其捐贈到 Apache 軟件基金會。在此,我們誠摯地邀請各位加入 Fluss 開源社區,共同促進這一新興項目的成長與發展。歡迎大家加入 Fluss 社區釘釘群 109135004351,歡迎大家一起探索,參與開發和貢獻,并攜手構建下一代的流存儲技術!

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容