
摘要:本文整理自餓了么大數(shù)據(jù)架構(gòu)師、Apache Flink Contributor 王沛斌老師在8月3日 Streaming Lakehouse Meetup Online(Paimon x StarRocks,共話實時湖倉架構(gòu))上的分享。主要分為以下三個內(nèi)容:
- 餓了么實時數(shù)倉演進(jìn)之路
- 實時湖倉方案選型與探
- 實時湖倉規(guī)劃及展望
一、餓了么實時數(shù)倉演進(jìn)之路
1. 餓了么典型實時應(yīng)用場景

以上是餓了么在實時應(yīng)用中的一些典型場景,和許多公司有相似之處。具體分為以下幾個部分:
(1)實時 ETL:包括實時數(shù)據(jù)入湖入倉、實時數(shù)據(jù)建模、實時流量歸因等。
(2)實時報表應(yīng)用:包括營銷活動直播、商家生意參謀、實時流量大盤、大促實時大屏、實時AB實驗等。
(3)實時與在線應(yīng)用的聯(lián)動:包括商物流實時聯(lián)動、實時人群特征及投放、個性化推薦、IOT信息同步、風(fēng)控實時攔截等。
(4)實時監(jiān)控與補償:包括實時數(shù)據(jù)核對與訂正、業(yè)務(wù)診斷預(yù)警、服務(wù)器異常監(jiān)控等。
2. 餓了么數(shù)據(jù)架構(gòu)大圖

餓了么整體數(shù)據(jù)架構(gòu)大圖主要由三個層面組成,分別為數(shù)據(jù)采集層,數(shù)據(jù)加工層,數(shù)據(jù)服務(wù)層。相關(guān)的數(shù)據(jù)組件依托阿里云組件。整體數(shù)據(jù)采集使用 DataX 和 DRC 鏈路來進(jìn)行數(shù)據(jù)庫 Binlog 的采集。日志采集主要使用內(nèi)部的 Omni 平臺來收集用戶行為數(shù)據(jù),而應(yīng)用層的日志通過 SLS 和 TT 來進(jìn)行相應(yīng)的日志接入。
數(shù)據(jù)倉庫這一層是一個重點。一個是存儲方面可以分為兩塊:一塊是近實時的湖倉,采用 Paimon On OSS 方案來進(jìn)行存儲;而對于實時性要求更高的數(shù)據(jù),使用的是 TT 和 SLS。在數(shù)倉計算層,使用的是 Dataphin、VVP(實時計算 Flink) 和 Flink 三件套。在數(shù)據(jù)服務(wù)層,主要的數(shù)據(jù)存儲使用 ADB 和 Hologres,最近引入了 StarRocks 來結(jié)合湖倉進(jìn)行落地。在這個存儲基礎(chǔ)上,通過內(nèi)部的數(shù)據(jù)服務(wù)應(yīng)用(包括繁星、方舟、FBI、量子等組件)來提供相應(yīng)的數(shù)據(jù)服務(wù)。通過以上數(shù)據(jù)服務(wù),構(gòu)建了整體的數(shù)據(jù)產(chǎn)品和數(shù)據(jù)解決方案。
最核心的兩個點是計算和存儲。上圖右邊展示了整體計算變化的情況。右邊第一張圖顯示了我們內(nèi)部 Blink 和 Flink 的用量曲線??梢杂^察到,早期更多使用的是 Blink,隨著 Flink 的進(jìn)一步拓展,到2023年左右,開始大規(guī)模切換到 Flink。計劃在今年將所有 Blink 下線,全部統(tǒng)一切換到 Flink。第二張圖顯示的是存儲層的情況。存儲層早期更多使用的是 ADB,現(xiàn)階段更多使用 Hologres 來支持。未來 Hologres 的用量也會逐步擴大,并引入類似 StarRocks 這樣的 OLAP 引擎,以提升團(tuán)隊整體研發(fā)效率。
3. 實時數(shù)倉1.0
基于上述的兩個背景,接下來介紹一下我們內(nèi)部當(dāng)前實時數(shù)倉建設(shè)的情況。

實時數(shù)倉的1.0版本中,這是大多數(shù)公司早期版本的典型樣子。我們通過日志和數(shù)據(jù)庫的 Binlog 進(jìn)行數(shù)據(jù)采集,這些數(shù)據(jù)最終進(jìn)入 ODS 層。在 1.0 版本的早期階段,我們投入了大量工作來建設(shè) DWD 層。在 DWD 層,我們對一些共性的維度和邏輯進(jìn)行了擴展,并屏蔽了多余的場景,建設(shè)了完善的 DWD 層群以供下游消費使用。
對于不同的應(yīng)用場景,我們開發(fā)了相對獨立的 ADS 層,這一層并未進(jìn)行公共層的建設(shè)。而對于核心業(yè)務(wù)場景,我們采用了 Lambda 架構(gòu)將歷史數(shù)據(jù)通過 T+1 的方式導(dǎo)入到 OLAP 引擎中,以保證數(shù)據(jù)的穩(wěn)定性。在此過程中會出現(xiàn)幾個問題:首先是研發(fā)效率較低的問題,會產(chǎn)生較多的重復(fù)開發(fā)工作。其次,隨著業(yè)務(wù)的變化,這些邏輯往往無法及時同步更新,導(dǎo)致數(shù)據(jù)一致性缺乏保障。這不僅增加了整體的運維成本,也增加了計存成本。
基于上述情況,我們期望達(dá)成以下兩個目標(biāo):首先是確保數(shù)據(jù)能夠更快、更準(zhǔn)、更穩(wěn)、更一致;其次是提升整體的開發(fā)效率和運維效率。具體的解決方案總結(jié)為四個要點:
(1)數(shù)據(jù)產(chǎn)品能力升級,收斂實時需求。
(2)夯實實時的 CDM 資產(chǎn),收口指標(biāo)加工邏輯。
(3)實時數(shù)倉架構(gòu)方案升級,獲取技術(shù)紅利,降低研發(fā)復(fù)雜度。
(4)研發(fā)規(guī)范化及工具沉淀(流程卡點&實時基線等)。
4. 實時數(shù)倉2.0
上述第二點對應(yīng)的是實時數(shù)倉 2.0 的具體方案。具體方案是建設(shè)核心的 CDM 層,將常見的共性維度和指標(biāo)加工成 DWS 資產(chǎn)。這個方案是在去年年初提出的,整體方式是借助 Dataphin 來構(gòu)建一個流批一體化的系統(tǒng)。

實時的 DWD 和離線的 DWD 通過 Dataphin 的邏輯表進(jìn)行映射,在 Dataphin 上開發(fā)具體的 SQL 任務(wù)后, Dataphin 會將其翻譯成 Flink 的流任務(wù)和批任務(wù)。在此基礎(chǔ)上,結(jié)合 D2 的 Dataworks,根據(jù)每一個調(diào)度將每天的 T+1 任務(wù)觸發(fā),最終將數(shù)據(jù)回寫到 OLAP 集群中。通過 OLAP 集群的 Binlog 來驅(qū)動下游的實時消費。這樣下游的 ADS 層只需進(jìn)行現(xiàn)有指標(biāo)的簡單統(tǒng)計或行列轉(zhuǎn)化后將數(shù)據(jù)寫入各自的存儲以滿足不同查詢場景的使用和需求。
完成這條鏈路后,整體的核心資產(chǎn)消費鏈路和研發(fā)效率得到了提升,數(shù)據(jù)一致性也得到了保障。然而,仍然存在一些問題。例如它主要支持存量的重要業(yè)務(wù),對于一些新興業(yè)務(wù)這條鏈路并不適用。另外這鏈路并未完全實現(xiàn)流批一體化的目標(biāo)。在 DWD 層數(shù)據(jù)實際上還是有兩份存儲,一份在 TT,一份在 ODPS。
此外,實時中間層更多使用的是 TT,但 TT 不支持檢索和更新。在研發(fā)或數(shù)據(jù)訂正的過程中,這會帶來較高的成本。同時,TT 也不支持列裁剪。以流量中間層為例每次消費都會產(chǎn)生大量的帶寬費用。再者,OLAP 集群內(nèi)表存儲成本往往比較高。因此,無論是從降低成本還是提升效率的角度來看,我們都希望引入更好的數(shù)據(jù)架構(gòu)。因此,我們找到了當(dāng)前比較熱門的解決方案 —— Streaming Lakehouse。
二、實時湖倉方案選型與探索
那么我們想引入 Streaming Lakehouse 要如何實施呢?首先要做的就是具體的選型和探索落地的實踐。
1、選型與測評方案

在整個選型過程中,使用了餓了么最核心的交易、營銷和流量三個域的明細(xì)數(shù)據(jù)作為測試數(shù)據(jù),并將數(shù)據(jù)寫入對應(yīng)的湖存儲格式中。我們當(dāng)時評測選擇了 Paimon + Hudi 這兩種湖格式。為了方便整體驗證還與現(xiàn)有的 OLAP 集群的內(nèi)表方案進(jìn)行對比。
在 OLAP 引擎方面,主要引入了 StarRocks、Trino 引擎進(jìn)行對比。在存儲層,我們主要關(guān)注數(shù)據(jù)寫入后的膨脹系數(shù)、流讀和流寫的性能,以及端到端的寫入延遲。在 OLAP 部分,我們重點關(guān)注查詢的耗時和單次查詢的開銷。
上圖左邊展示了我們在整個評測中所使用的版本。整體使用的集群規(guī)模大約為 200CU。由于規(guī)格的原因, StarRocks 的集群總共是 192CU。在這些組件中,大家比較關(guān)注的 StarRocks 和 Trino 我們是直接采用了阿里云的 EMR 5.15.1 版本進(jìn)行部署的。
2、Paimon VS Hudi

Paimon 和 Hudi 哪個更優(yōu)呢?
圖中左上角展示了經(jīng)過多輪測試后得出的結(jié)果,整體排名基本上都是 Paimon 優(yōu)于 Hudi。同時,Paimon 的性能也接近 OLAP 集群內(nèi)表方案的查詢性能。但是在端到端的時效性方面,OLAP 集群內(nèi)表方案仍然是最快,可以達(dá)到秒級別。Paimon 的時效性測試結(jié)果大約在1到5分鐘,平均約為3分鐘。Hudi 在這一塊的延遲一般在10分鐘左右。
基于上述測評結(jié)果,選擇 Paimon 作為后續(xù)的湖存儲格式。結(jié)合前面提到的三個月具體場景,上圖可以看到對應(yīng)的 Paimon 表的創(chuàng)建方式。對于交易和營銷數(shù)據(jù),由于需要實時更新,因此我們使用了一個PK表,指定了 Bucket 并同時開啟了 ZSTD 壓縮。在這個過程中,還需要通過 Sequence Field 進(jìn)行版本控制。流量表則是一個 Append Only 表,基本上設(shè)置為 Bucket=-1,以支持自動化擴展。同時為了保障讀寫的性能平衡,所以每一個文件大概需要控制在一個 GB 范圍內(nèi)。
3、StarRocks VS Trino
在對比 StarRocks、Trino 的性能時,StarRocks 在各個方面都表現(xiàn)比較出色。是什么原因使得 StarRocks 的性能如此出色呢?首先,StarRocks 的 JNI Connector 對 Paimon 進(jìn)行了良好的適配。其次,StarRocks 支持過濾下推。上圖右下展示了餓了么基于 StarRocks 的一個 profile 截圖,可以看到 “city_id” 和 “is_valid_order” 這兩個字段實現(xiàn)了有效的下推。此外,StarRocks 還具備高效的向量化執(zhí)行引擎,并且可支持對 Paimon 的 RO 表進(jìn)行查詢。最后,雖然我們目前還沒有正式使用物化視圖 +SQL 透明改寫和 Data Cache 這兩個功能,但可以預(yù)見一旦投入使用性能將會進(jìn)一步提升。在這樣的背景下,餓了么最終選擇使用 StarRocks 和 Paimon 作為湖倉解決方案。
4、實時湖倉落地探索

經(jīng)過多次探索,我們確定了如上圖所示的湖倉建設(shè)架構(gòu)。主要的數(shù)據(jù)處理鏈路使用 Flink 進(jìn)行 Paimon 的流讀流寫,Paimon 的數(shù)據(jù)存儲在內(nèi)部 OSS 集群上,并通過 DLF(Data Lake Formation)進(jìn)行元數(shù)據(jù)管理。通過 Paimon 的流讀流寫功能,支持實時數(shù)倉的分層建模。在特定場景下,利用 StarRocks 的物化視圖進(jìn)行應(yīng)用層或匯總層的計算。同時基于明細(xì)數(shù)據(jù)通過 StarRocks 和 Hologres 的數(shù)據(jù)湖外表查詢能力支持自助洞察分析的需求。具體應(yīng)用場景包括:流量寶洞察分析、實時交易補貼自助分析以及客滿的服務(wù)大屏等。
5、落地探索-DWD自助分析

接下來主要介紹基于交易和補貼的自助分析場景。首先,數(shù)據(jù)源提供訂單流和補貼流兩個實時流。在傳統(tǒng)方案中,這兩個流在Flink任務(wù)中進(jìn)行雙流 Join 處理后寫入 OLAP 集群內(nèi)表,再基于 OLAP 集群內(nèi)表提供自助分析服務(wù)。引入 Paimon 之后,兩條流直接寫 Paimon 的 Partial-update 表,指定不同流中的 Sequence Group 來進(jìn)行對應(yīng)字段的版本控制。在這種情場景下,整體 Flink 的資源開銷相比原來的雙流 Join 方案減少了大約50%,同時系統(tǒng)的整體穩(wěn)定性也顯著提升。
然后在 StarRocks 這一層,通過 StarRocks 來讀 Paimon 外表這塊來支持的。上圖右上角是整體的 Profile 的結(jié)果,可以看到大部分的瓶頸其實還是在 IO 這一層的。所以后續(xù)如果做數(shù)據(jù)湖的加速分析的話,IO 這一層還是優(yōu)化的重點。
上圖右下角展示了整個自助分析的結(jié)果示意圖。與之前基于 OLAP 集群內(nèi)表的實時數(shù)倉方案相比,這個方案在寫入時效性上犧牲了1到5分鐘,同時單次查詢的耗時增加了約5%。然而,整體存儲成本較原有的 OLAP 集群內(nèi)表減少了約90%,F(xiàn)link 任務(wù)的資源開銷也減少了大約50%。
三、實時湖倉規(guī)劃及展望
1、實時數(shù)倉3.0 展望

如果建設(shè)了實時湖倉,后續(xù)的加工鏈路可以進(jìn)一步豐富,從而構(gòu)建不同場景下的數(shù)據(jù)解決方案。相比之前的實時數(shù)倉2.0版本,DWD 層和 TT 層將逐步替換為數(shù)據(jù)湖。使用數(shù)據(jù)湖后,可以針對低頻場景構(gòu)建準(zhǔn)實時或?qū)崟r的物化視圖,通過物化視圖進(jìn)行分層建模。同時,還可以利用 Paimon + Flink 的流讀流寫能力進(jìn)行分層建模。在數(shù)據(jù)服務(wù)層,可以根據(jù)業(yè)務(wù)需求按需查詢對應(yīng)的 DWD、DWS 或 ADS 層,從而構(gòu)建多元化的數(shù)據(jù)交付方案。
具體的交付方案如上圖左下角所示,不同場景可以選擇不同的交付方案,利用現(xiàn)有的實時數(shù)據(jù)資產(chǎn),提升研發(fā)效率。然而這邊仍會遇到一些問題:OSS 帶寬瓶頸在壓測過程中已經(jīng)顯現(xiàn)出來需要解決,同時 OSS 上的小文件問題也是亟需解決的。Paimon 的時效性目前為1到5分鐘,對于強時效性訴求的業(yè)務(wù)仍需要保留 TT 鏈路。雖然 Paimon 和 StarRocks 現(xiàn)有的元數(shù)據(jù)可以通過 DLF 管理,但與內(nèi)部原有的元數(shù)據(jù)管理缺乏打通,需要進(jìn)一步拓展。此外,目前集群的權(quán)限控制相對較弱的,需要進(jìn)行強化。
右邊展示了后續(xù)希望重點推進(jìn)的幾個方面。首先是 StarRocks 物化視圖,之前進(jìn)行了輕度測試,因遇到一些問題,暫時未能顯著提升研發(fā)效率,未來希望重點完善這一方案。此外,在 Flink 寫入 Paimon 時,常因 Compaction 問題導(dǎo)致顯著抖動,計劃采用異步 Compaction 機制,以保障整個實施鏈路的穩(wěn)定性。此外,諸如期望引入 Deletion Vector,顯著提升查詢效率。
目前,Paimon 實時中間層已應(yīng)用于一些核心鏈路,未來希望將其推廣到更多數(shù)據(jù)場景。還計劃與 DataWorks 和 MaxCompute 進(jìn)行集成,這屬于生態(tài)系統(tǒng)建設(shè)的一部分。在 OSS 方面,我們希望通過冷熱分層能力進(jìn)一步降低成本。之前嘗試結(jié)合 Paimon 的 Tag 機制來實現(xiàn)這一目標(biāo),但暫時還未找到理想的解決方案。
2、回顧

最后回顧一下餓了么整體實時數(shù)倉的建設(shè)歷程,大致可以分為幾個階段。首先是相對原始的開發(fā)階段,這一階段主要建設(shè)實時的 DWD 層,各個應(yīng)用層通過 Flink 任務(wù)各自生成自己的 ADS 數(shù)據(jù)。在這一過程中,ADS 層出現(xiàn)了大量數(shù)據(jù)一致性問題和重復(fù)開發(fā)的問題。為了解決這些問題,我們構(gòu)建了實時的 CDM 層,從而解決了共性問題。然而,對于新增業(yè)務(wù)和場景的支持仍顯不足。因此,我們引入了實時湖倉方案。雖然該方案目前仍在探索階段,但已經(jīng)在一些具體場景中實現(xiàn)了落地。未來,我們希望在 Paimon 和 StarRocks 上進(jìn)行更多的探索和應(yīng)用。