字節(jié)、阿里關于實時數據湖的應用與解決方案總結
在海量數據下,依靠傳統數據庫和傳統實現方法基本完成不了,企業(yè)需要一種分布式的、高吞吐量的、延時低的、高可靠的實時計算框架。
下面將為大家分享字節(jié)跳動、阿里2家企業(yè)在實時數據湖的方面的實踐應用。
01 實時數據湖在字節(jié)跳動的實踐
近兩年數據湖是一個比較火的技術,從傳統的數倉到數據湖,在過去 5 年里架構演變得非常迅速。Hudi、Iceberg、Dalta Lake在業(yè)界被稱為數據湖三劍客。
目前,字節(jié)對數據湖的解讀,主要聚焦在數據湖的六大能力上:高效的并發(fā)更新能力、智能的查詢加速、批流一體的存儲、統一的元數據和權限、極致的查詢性能,以及AI + BI。
字節(jié)內部的數據湖最初是基于開源的數據湖框架Hudi構建的,在嘗試規(guī)模化落地的過程中,主要遇到了四個挑戰(zhàn):數據難管理、并發(fā)更新弱、更新性能差,以及日志難入湖。
如何應對這些挑戰(zhàn)?字節(jié)做了問題背后的詳細的原因分析,以及針對不同問題,采取了不同的應對策略。
1. 構建一層統一的元數據層
為了解決數據難管理的問題,字節(jié)在數據湖和數倉之上,構建了一層統一的元數據層,這層元數據層屏蔽了下層各個系統的元數據的異構性,由統一的元數據層去對接 BI 工具,對接計算引擎,以及數據開發(fā)、治理和權限管控的一系列數據工具。
2.使用樂觀鎖重新實現并發(fā)的更新能力
多任務的并發(fā)寫入是字節(jié)內部實踐當中一個非常通用的訴求。因此字節(jié)在Hudi Metastore Server的Timeline之上,使用樂觀鎖去重新實現了這個并發(fā)的更新能力。同時,字節(jié)的并發(fā)控制模塊還能支持更靈活的行列級別并發(fā)寫策略,為實時數據關聯的場景的落地提供了一個可能。
與此同時,在進行高QPS入湖的情況下,字節(jié)遇到了單個Flink任務的擴展性問題和批流并發(fā)沖突的問題。如何解決?
- 通過在Flink的 embedding term server上支持對當前進行中的事務元信息進行緩存,大幅提升單個任務能夠并發(fā)寫入的文件量級。
- 提供更靈活的沖突檢查和數據合并策略——行級并發(fā)、列級并發(fā)和沖突合并。
3.采用可擴展數據結構hash
在早期的落地過程當中,字節(jié)盡可能地復用Hudi的一些原生能力,比如Boom Filter index。但Bloom Filter存在假陽性,規(guī)模達到一定量級之后,大部分數據都是更新操作,沒有辦法再被索引加速。
Bloom Filter索引的問題,根因是讀取歷史數據進行定位,導致定位的時間越來越長。對此,字節(jié)采用可擴展數據結構hash,無需讀歷史數據,也可以快速定位到數據所在位置。
利用這個數據結構結構,可以很自然地做桶的分裂和合并,讓整個bucket的索引從手動駕駛進化到自動駕駛。在數據寫入的時候,也可以快速地根據現有的總數,推斷出最深的有效哈希值的長度,通過不斷地對 2 的桶深度次方進行取余的方式,匹配到最接近的分桶寫入。
?
4.提供無索引的機制
日志難入湖的本質原因在于Hudi的索引系統,這個索引系統要求數據按照組件聚集,會帶來性能上的問題以及資源上的浪費。
無索引,即繞過Hudi的索引機制,做到數據的實時入湖。同時因為沒有主鍵,Upsert 的能力也失效了。字節(jié)在這方面提供了用更通用的 update 能力,通過shuffle hash join和 broadcast join 去完成數據實時更新。
02 阿里基于Flink Hudi的增量ETL架構
過去半年,阿里巴巴計算平臺事業(yè)部 SQL 引擎組一直在開發(fā)Apache Flink sql 模塊,核心工作是 Flink 與 Hudi 的集成。
為什么選擇Hudi而不是Iceberg或Dalta Lake?
這與Hudi的兩個能力有關系,一個是事務管理能力,另一個是upsert 能力。Hudi 提供的事務模型是快照級別,初步實現了海量數據 upsert 以及事務的管理能力。
1.Hudi如何做到近實時的數據庫入湖?
最近興起的流批一體的架構,像debezium、canal 通過訂閱 MySQL binlog 事件的方式將增量數據近實時地導入數倉之中,這就要求下游數據庫本身有 upsert 語義,而 Hudi 提供了這樣的能力,并且是目前做得比較成熟的,因此 Hudi 可以使用這兩種途徑至少在 ODS 層進行近實時的數據庫數據入湖:
先使用debezium 采集 binlog,在使用 flink cdc connector 直接對接,flink cdc connector 具有 snapshot 再加增量消費的能力,可以直接向下游擁有 upsert 的數據湖(如hudi)進行同步,不需要再去接一層 kafka 就可以做到分鐘級別的入倉入湖。
2.阿里如何構建分鐘級別近實時的增量數倉模型?
用傳統的方式構建經典的數倉模型,需要通過調度系統按照某種時間策略構建一個定期的 pipeline 任務,依據 pipeline 之間的依賴關系規(guī)定觸發(fā)機制,整體維護十分復雜。
Hudi 因為具有 upsert 的能力,因此可以利用 debezium 等工具,通過 flink CDC 加 kafka 將數據庫數據近實時地同步到 ODS 層。如果Hudi 可以繼續(xù)將上游數據的變更數據流傳到下游,借助 flink CDC 的能力下游可以繼續(xù)消費這種增量數據,然后在原有狀態(tài)的基礎上繼續(xù)做增量計算。因此,阿里通過對 hudi table format 進行改動,構建了分鐘級別近實時的增量數倉模型。