從離線到實時資料生產,網易湖倉一體設計與實踐

danny_2018發表於2023-05-06

本文根據周勁松老師在【第十三屆中國資料庫技術大會(DTCC2022)】線上演講內容整理而成。

隨著大資料實時化程式的不斷推進,實時與離線在開發鏈路與資料儲存上割裂的問題逐漸凸顯,這不僅造成了實時與離線在開發人員與儲存成本上的雙倍投入,還造成了實時與離線指標不統一的問題。新的湖倉一體架構旨在統一實時與離線的資料儲存,進一步解決實時與離線割裂的問題。網易基於Apache Iceberg,在之上構建了一套湖倉一體系統——Arctic,該系統在廉價的資料湖之上統一了流批儲存,並提供了資料約束、結構自最佳化、資料一致性、實時訂閱和實時Join等特性。

資料開發現狀與痛點

網易的資料開發在幾年之前,還是以T+1 離線資料生產為主,資料來源頭來自資料庫或者大量業務日誌,比如客戶端的日誌、伺服器的日誌,或者是感測器的資料,大量的原始資料進入離線數倉後,會做資料分層的開發,資料分層是為了資料複用,而需求是多樣的,不可能每個需求都從原始到最終結果,都去做完整的一次資料處理,這樣會浪費大量儲存和計算成本。

分層,用的比較傳統的這種 ODS層、 DWD層、 DWS 層、 ADS層這麼一個架構,分層的資料主要儲存在 Hive 裡,計算引擎最開始用 Hive SQL,後面全部轉向了 Spark SQL,去做這樣的資料開發。

如果到了輕度匯聚層或者資料集市層的話,要去做一些實時分析,中間會用到Impala 這樣的系統,這是一個比較傳統的T+1的離線資料生產的過程,基本上都是凌晨開始去排程,然後在第二天的早上產出結果。

1)、初步引入實時化

隨著業務系統的發展,對資料分析需求的增加,企業就不再滿足於這種T+1的狀態。一天的資料延遲,現在已經不夠用了,希望資料分析可以是低延遲,特別是AI的一些應用,對資料延遲要求更高,這時就要引入實時的這麼一個鏈路。

實時鏈路,當時的做法跟現在很多企業一樣,那就是在T+1的鏈路之上,重新去構造了一個實時鏈路。實時鏈路的儲存用訊息佇列,計算引擎是 Flink。但是 ,Flink 在當初開始使用的時候,很難像 Hive一樣去做資料分層。所以,大部分人的業務都是根據實際的需求,就去寫一個Flink任務,從源頭把資料接進來,經過聚合清洗之後,寫到像Kudu這樣的實時的數倉裡面,然後在實時數倉裡面去做分析,或者可以直接接到其他支撐實時更新的系統,比如資料庫。

如此一來,原有的系統分成了兩條鏈路,實時這條鏈路基本上按需開發,沒有什麼很好的設計規範,可能會存在著很多的重複的計算,就是你有需求你就去開發。

2)、更復雜的實時化

隨著實時這條鏈路的業務越來越多,簡單地去寫一個 Flink 任務已經搞不定了,在實時場景下,邏輯會越來越複雜。比如:實時場景下,需要一些維度資料,以前在離線場景下,維度表是存在 Hive 上,一張 Hive 表就夠了。但是 Hive 表,沒辦法去做實時的點查詢。所以說我可能還要引入一些k v系統,比如說一套Hbase,然後在上面去做點查。

另外,實時鏈路沒有資料分層,資料複用度很差,資源浪費很嚴重。所以,開始在實時鏈路上去做一些資料分層,比如:會把一些清洗好的表,或者一些公共要使用的表,把它放到一個單獨的kafka topic裡面。當時,整個實時鏈路裡面,儲存還是以kafka為主,然後會引入 Hbase去做 k v,會去做簡單的分層,最終資料還是落到 Kudu上。在業務應用上, Kudu沒辦法儲存大量的歷史資料,因為成本比較高。所以,如果在業務使用的時候,如果既用到歷史資料,也用到最近實時的資料,會把這種歷史的 Hive 的資料和 Kudu裡面最近的資料在做一個業務層面上去做一個聚合統一之後,然後再返回給業務系統。

3)、流批分割的Lambda架構

在典型的 Lambda 架構與流批分割的這種資料開發模式下,遇到了什麼樣的問題呢?

第一,資料孤島的問題。只有離線的時候,業務架構非常簡單,儲存是一套系統,就Hive、 Hadoop,計算是用的Spark或者用Hive SQL。引入實時之後,我們用到的系統變得多樣化,比如:要用Hbase、kafka、Kudu,甚至很多業務系統用Doris,用ClickHouse。

簡單理解,企業需要去用不同的儲存系統,去滿足實時上面的一些需求。同時,這些儲存系統一般都需要獨立採購和部署,而且他們的成本相較於 Hive 這樣的分散式系統,其實成本會更高。並且,裡面的這些資料也沒辦法複用,在離線這邊還得再存一套,需要用一些同步工具把這些實時的資料再同步到離線裡面來。

第二,研發體系的割裂,主要是實時和離線用不同的語言開發,雖然要達成相同的業務目標,但是可能要用 Spark SQL 寫一遍,然後再用 Flink SQL 寫一遍,甚至有的SQL沒辦法表達。更復雜一點,可能要用不同的方法去實現,比如 :Stream API或者Batch API。

在大部分場景下,其實在公司內部,實時和離線開發同學是不同人員,他們在技術棧上存在著差異,由此造成研發人效低,研發規範不通用,實時和離線都要處理相同的需求。大家會各建各的表,各建各的任務。最終,還有一個更大的一個問題,大家產出的資料經常在使用的時候要去統一使用,雖然你要解決相同的需求,但是前面的語言,使用的表達定義都完全不一樣,怎麼能夠保證最終在使用的時候,或者說去聚合離線和實時產生接入的時候,保證資料的正確性呢?這就會帶出指標和語義的二元性問題!

基於Apache Iceberg的湖倉一體系統Arctic

面對上述問題,網易如何應對?新型的資料湖格式,主要有三種Iceberg、Hudi、Delta,他們有一個特點,就是可以做流批統一,不像之前傳統的Hive 表,只能去做離線寫入,實時寫入會很麻煩,因為沒有一套很好的ACID機制,同一個表只能有一個任務去讀,並且讀寫也不能併發。

換言之,你要去做流批一體的支援,首先需要去做這種讀寫併發的支援,其次這套儲存系統能夠去接受流式的去寫入,批次的寫入,也能夠去接受流式的讀取,批次的讀取,這是流批一體的基礎。而當時 Iceberg 和 Hudi 其實他們已經逐漸的有了這樣的能力,這種新型的資料湖格式都有統一的特點,比如:流批的讀寫介面都具備,同時得有ACID的能力,流批一體可以併發去讀寫。

此種背景下,網易透過引入新型的資料湖表格式去解決流批分割的問題。而且,像Iceberg、Hudi都有實時更新的能力,以前 Hive 肯定做不到,要去更新一條資料,可能就要對整個表進行重寫了。Iceberg、Hudi可以做到行級更新或者刪除一條資料,對於資料庫接入的資料就會非常友好,還可以流式地去實時更新湖倉裡面的資料。

至於,為什麼選擇Iceberg,而沒有選Hudi?是因為當時的Hudi對Flink沒有很好的支援!而企業內部的實時計算,基本上都是用 Flink 做的,投入網易內部去使用的其實是Iceberg,然後把Iceberg引入之後,的確解決了很多以前使用 Hive 上遇到的問題。

但是,同時也發現,想直接去使用Iceberg去解決前面提到的問題,其實是存在著一些挑戰。此種背景下,網易基於Iceberg自己研發了一套服務,並且現在開源了這套湖倉一體的管理服務。雖然,網易內部叫湖倉一體系統,但更準確的定義是湖倉管理服務,叫Arctic。

Arctic的底層儲存公司內部用的是HDFS,但外部應用很多都已經上雲,比如S3或者阿里雲的OSS,如果是訊息資料儲存,大部分會存在MQ上。MQ也是低延遲訊息的一種儲存,在這之上就是format和 service 層,再之上就是引擎層,包括 Spark 、Flink,一個去做批次的這種任務開發,一個去做實時的任務開發,然後 presto、Trino 這些去做了一些 AP 分析,它都是我們的計算引擎。中間兩層其實就是核心應用會覆蓋到的兩個層級,而Iceberg自己就是一個很好的format,所以可以直接用iceberg 作為table format。

但是,前面提到直接用Iceberg 去做table format,可能在某些業務場景下還是會有些問題,所以網易在Iceberg 之上做了重新設計,也就是Mixed streaming format,它最大優勢是面向這種流式場景,去補足暫時現階段Iceberg可能存在的一些不足。

但是,Mixed streaming format和Iceberg format包括Hive format,都可以理解是並行的格式,你在這套系統裡面用哪一種 format 的表都沒有問題。其次,在這套系統裡面,不只是一個純粹的面向資料湖、面向檔案的這麼一個儲存系統,還是會去考慮實時場景下,需要訊息佇列提供的這種毫秒級延遲,所以說它還要用 log format 這樣的概念。log format在我們的訊息佇列之上,訊息佇列設計的格式也是放在Mixed streaming format之下。

再上層,就是 service 層,主要有兩核心,一個就是AMS(Arctic Management service)這麼一個服務,它會去儲存一些後設資料,同時還有資料湖裡的一些管理能力,包括對資料湖裡面的表去做監控,去做最佳化。透過optimizer container一套完整的資源管理,可以去做分散式的多表併發的最佳化。optimizer 要排程到不同的基礎設施上,比如k8s、yarn或者直接排程到物理機上,不同的排程方式會有不同的 optimizer container 實現。

一個 optimize container對應著一個叢集,這個叢集裡可能有不同的佇列,即optimizer group。在這個佇列內部會起很多的任務,那就是optimizer。對於很多表,會去選擇一個optimizer group,你的表的所有的這種最佳化的任務都會放在 group 下,不同的表放到不同的 group 下,就可以去做到資源隔離。那Ams + optimizer ,這套機制就是網易現階段service 層的一個核心。

面向開放式架構的諸多功能創新

arctic是一個開放式架構下的湖倉管理系統,首先它面向開放式架構,面向不同的 table format。現在,主要面向 Iceberg format,然後企業自己也在Iceberg之上有一套Mixed streaming format的實現。以後也會去嘗試去對接更多的 table format,比如說 Hudi 或者Delta,我們認為他們有管理最佳化等相同的需求,arctic 都是可以作為一套湖倉管理系統去對接這些format。arctic是在開放的表格式之上,首先它與Iceberg 、Hudi不是競爭關係,arctic是這些技術之上的管理服務。Arctic面向場景更多地關注流和實時更新的場景,並且提供一套可插拔的資料自最佳化的管理服務。

以Schema evolution為例,前面提到的Iceberg format,那它就是原生的 Iceberg 表。也就是說,如果你已經是Iceberg的使用者,你已經在用Iceberg表了,那你可以非常輕量的把arctic作為一個管理服務單獨部署起來。相較於以前傳統的Hive 表,Iceberg format表結構可以支援非常自由的變更。Hive 表的表結構變更其實是有一些限制的,因為 Hive 下面的檔案有自己的schema,它自己也存了表的 schema 資訊,他們之間是用名字去做對映。這種情況下,去做一些結構變更,可能就會有些風險,比如要做一些 rename 變更,rename完了以後發現,在老的檔案裡面已經找不到這一個欄位了,那老的資料就會讀不到了。在網易內部,Hive只會去做一種schema 非同步,就是加欄位,那這樣的話會很大程度地限制源端資料庫,只能加欄位。

再比如:Hidden partitioning。如何理解呢?使用 Hive 的使用者和使用資料庫的使用者,可能在 partition 上面的理解上其實是有很大的不足。Hive 的 partition是一個額外的欄位,這些額外的欄位你要在寫入的時候寫進去,讀的時候要把這個額外欄位作為一個條件,放到額外條件裡,這樣才能夠用到這些分割槽的能力。

但是,對於資料庫的使用者,建立分割槽本身它是一個運維側的事情,對於業務來說,寫入和查詢都不考慮分割槽,我直接按業務欄位的條件去寫 SQL 就好了。那 Hidden partitioning 就是用一樣的概念,你的分割槽不再是一些表上的額外欄位,你在寫入和讀取的時候也不用再去關心它,只是你表中已有欄位上面的一些轉換關係。比如:要在一個時間欄位上按天去做分割槽,那你這個分割槽配置就是在時間欄位上一個取天的一個函式,然後以後你在這個時間欄位上去做條件的過濾,它就可以自動的去對映到分割槽上面,幫你去做高效的過濾了。

與此同時,Time travel(解決冗餘資料儲存問題)、Serialization isolation(資料一致性解決方案)、 Fast scan planning(快速找到需要讀的檔案)等等,都是Iceberg format一些功能優勢,這裡不詳細贅述!

而Mixed streaming format關鍵特性是:更強的主鍵約束和流批通用 、Auto-Bucket 提升 OLAP 效能 、LogStore 提供秒級 Data pipeline 、Hive / Iceberg 格式相容 、事務衝突解決機制。包括Self-optimizing可以解決自動、非同步與透明問題,資源隔離與共享,以及靈活可擴充套件的部署方式等。

未來規劃

從 IT 定位來說,湖倉一體核心內容就兩塊,一個是更強的管理能力,另一個就是更強的OLAP效能,未來網易會在這兩個方面繼續增強。比如:資料湖許可權問題、更多的監控項以及熱表與慢查詢、多資料中心和多雲管理等等。同時,OLAP方面,會支撐更好的排序,去提升排序欄位上的這種範圍查詢的效能。雖然Iceberg 也有sort order 的能力,但只能有一套sort order,你的資料和查詢條件非常多,引入太多的排序欄位,可能最終也得不到一個很好的效能。一個方向是,要根據不同的這種排序欄位去建立不同的副本,來提升你的查詢能力。

另外,聚合key,我們可以理解為預聚合,透過Arctic能不能去做一些預聚合的事情?這些都建立在base store、 change store架構之上,每個 base store 有不同的排序規則,change store寫進來的都是CDC資料,能夠做排序和聚合支援,包括可以支援二級索引。其中,Mixed streaming format是OLAP效能提升的一個關鍵!

嘉賓介紹:

網易平臺研發專家 周勁松

從事大資料與資料庫方向開發工作7年,曾負責網易分散式資料庫與資料傳輸系統的研發工作,目前作為Arctic流批一體資料湖的專案負責人,在構建資料基礎設施方面有著充分的開發與實踐經驗。

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

相關文章