B 站基於 Iceberg 湖倉一體最佳化實踐及智慧化管理平臺的助力

qing_yun發表於2023-01-28

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

講師介紹

【嘉賓介紹】嗶哩嗶哩 OLAP 資深開發工程師,十多年軟體行業從業經驗,四年多大資料 OLAP 方向研發經驗,先後在唯品會、B 站從事大資料 OLAP 方向的研發工作,目前主要負責B站OLAP平臺,湖倉一體方向:Iceberg 核心研發、最佳化探索實踐,智慧化管理平臺搭建、以及業務接入支援等相關工作。

本文摘要:本文整理自向阿鯤在DTCC2022大會上關於“B站基於Iceberg湖倉一體最佳化實踐及智慧化管理平臺的助力”的主題演講,主要介紹了Iceberg 湖倉一體專案在B站的落地實踐,Iceberg 湖倉一體的核心最佳化,智慧化管理平臺的背景、意義與實踐,以及未來展望。

分享大綱:

1、湖倉一體專案在 B 站 OLAP 平臺的落地實踐

2、基於 Iceberg 湖倉一體核心最佳化

3、智慧化管理平臺 Magnus

4、未來規劃

以下為演講正文:

湖倉一體專案在 B 站 OLAP 平臺的落地實踐

為什麼引入湖倉一體?

第一部分先簡單介紹一下B站湖倉一體專案的背景。下圖是我們早期資料服務架構,藉此來展開為什麼會引入湖倉一體。

先介紹一下基礎資訊:在B站,大資料平臺主要依託 Hadoop生態。我們看一下架構圖的左側,資料來源經過 ETL 會把資料 load到不同的資料庫引擎,像 ES、TiDB,ClickHouse、InfluxDB,以及HBase 等。然後透過一個統一的查詢服務對接不同的資料庫引擎,為不同的資料產品提供查詢服務。這樣一套架構會存在一些問題:

首先資料出倉繁瑣,資料一致性很難保障,因為同一份資料可能存在不同的儲存系統裡面。二是資料處理複雜,需要定製化。此外,為了提高查詢效能,需要為不同的儲存引擎最佳化計算。

引入湖倉一體架構

針對以上痛點,B站引入了湖倉一體架構,並啟動了湖倉一體專案。湖倉一體專案是在Hadoop生態上引入了Iceberg元件,透過在Iceberg元件上的一系列最佳化,在擁有資料湖靈活性的同時,打造了一套高效能的數倉的體驗。

湖倉一體的資料流轉圖如上,左邊是資料採集,目前B站的資料來源主要有 APP 埋點資料,MySQL業務資料,服務 log 日誌等。透過公司內部統一的傳輸服務Lancer 進行資料分發,主要分兩條鏈路:

一、透過Flink近實時地寫 Iceberg 表,預設 5 分鐘一個checkpoint。另外一條鏈路是天級或者小時級,落入到Iceberg表。Iceberg表無論在ODS、DWS、DWD的哪一層,都可以根據使用者需求對外直接提供服務,目前最多的業務場景是使用 DWD層明細層資料直接對外提供服務。

資料匯入後,會由智慧化管理平臺 Magnus,後臺進行非同步地資料組織最佳化。

資料分析側:透過統一的計算引擎Trino作為查詢的統一入口,同時也引入了 Alluxio作為快取加速,以及保證查詢的穩定性。

對效能有極致需求的場景,我們會將Iceberg表的資料出倉到ClickHouse,但是整體上使用者可以直接基於Iceberg表進行OLAP查詢分析。

湖倉一體的架構有不少優勢,解決了此前資料服務架構的很多痛點。首先資料不用出倉,避免了資料重複儲存。其次,大資料可以新增索引,支援毫秒級/秒級查詢能力,滿足基本取數場景。再者,從資料處理到取數過程大大縮短,資料處理也就更加高效了。同時,支援資料增量 update,支援事務,能對接更多業務場景。

目前湖倉一體專案在 B 站 OLAP 平臺的落地場景主要有資料服務(取數服務)、ABTest 實驗平臺、BI 報表、標籤人群圈選、日誌檢索等。如取數服務,主要對接公司的運營後臺、資料產品(萬華鏡、觀星臺、Boss 看板等),以及OLAP多維分析場景。計算引擎Trino的單叢集QPS峰值可以達到 300 QPS,資料產品萬華鏡目前的平均查詢耗時大概在 200 毫秒。

基於 Iceberg 湖倉一體的核心最佳化

資料組織排序

Iceberg提供了檔案級別後設資料,像manifest 檔案索引了所有的資料檔案,並儲存了資料檔案的一些元資訊,如資料檔案路徑、具體有哪些列,以及每個列的Min/Max值等。計算引擎可以利用Iceberg提供的檔案級別元資訊進行高效查詢過濾。

假如不對資料進行任何最佳化,直接利用Iceberg提供的後設資料:欄位在檔案內的Min/Max值。如左上圖,存在 column: Id,它的Min/Max 值在所有檔案內都是比較分散的,如果透過id = 100 做過濾,由於每個檔案的跨度都比較大,都可能包含100這個數值,這樣就沒辦法直接過濾任何檔案了。

透過對Iceberg表進行資料組織排序,可以使得檔案根據欄位Id有很好的聚集性。如上圖右邊部分,透過排序之後,再用 Id =100進行查詢,只需要讀第一個檔案就行,另外 3 個檔案透過後設資料的 Min/Max值就可以直接過濾掉,這種情況下不需要去掃描所有的檔案了,可以大大提高查詢效能。

上面舉例的是一個線性排序的場景:基於一個或多個欄位進行分割槽內線性全排序,典型應用場景包括:根據 up_id/avid 進行點查/範圍查詢。線性排序遵循最左匹配的原則,如果第一個欄位是一個高基數字段,根據它排序之後,大機率第二個欄位是無序的,根據第二個欄位去做過濾,通常無法直接過濾掉任何資料檔案。

由於線性排序的缺陷,我們內部實現了 Z-order 排序, Z-order 排序基本原理如下:多個待排序欄位,分別按照大小進行二進位制編碼,每組欄位根據編碼後的值按 bit 位交錯生成一個 Z-Value 值,使得生成的 Z-Value 沿著特定空間軌跡是有序的。

如上圖的左邊部分,Z-Value 沿著 Z字形曲線,對應取值分別是 0、1、2、3… ,是依次遞增的。即沿著Z字形是有序的,這也是 Z-order排序名字的由來。

透過 Z-order 排序之後,把左邊的圖從 x 跟 y 分別從中間做切分,把資料切分成 4 個檔案,得到右邊圖的效果。第一個檔案 x 取值範圍是 0- 3, y取值範圍0- 3,其他幾個檔案類似。這種情況下,假如是用 x = 1 過濾,只需要去掃描左上角第一個檔案和左下角的檔案即可。如果用 y = 5 去過濾,只需要去掃描左下角跟右下角的資料檔案就可以。這個場景,不管是用 x 還是 y 進行過濾,都有 50% 的過濾效果。當資料越多,生成的資料檔案越多,經過 Z-order 排序後,單個欄位過濾可以達到80%-90%的過濾效果。

在實際應用場景中,Z-order排序通常會基於 2~4 個欄位進行分割槽內 Z-Order 空間排序。實際測下來,如果Z-order排序的欄位過多,比如超過 4 個欄位,過濾效果大打折扣。Z-order排序典型應用場景有根據 up_id、avid、time 等多個欄位進行點查/範圍查詢。

二級索引支援

二級索引支援:Bloomfilter 索引,很小的儲存開銷,支援任意普通型別欄位的點查。典型應用場景包括存在較多不同欄位過濾場景,適用於相對較高基數的欄位;Bitmap 索引:支援多個欄位的組合查詢,並且支援範圍查詢。典型應用場景包括單個欄位或多個欄位組合的點查或範圍查詢,欄位基數不宜過高;BloomRF 索引:較小的儲存開銷,支援欄位的點查和範圍查詢。典型應用場景包括高基數字段的點查和範圍查詢;Tokenbf、ngrambf 索引:針對 String 型別資料進行檢索,典型應用場景為日誌場景中的關鍵字檢索。

經過資料組織排序,多種二級索引支援,在SSB 1000大寬表模式進行效能測試,整體來看,查詢時間有 1- 10 倍查詢效能提升。讀檔案數量效能提升更為明顯,有2-400倍的讀檔案減少。

預計算、星型模型支援

星型模型最佳化是指在 join 場景下,根據維表過濾欄位。透過關聯維表,按照維表欄位進行資料重新組織,查詢時將維表謂詞直接進行下推。

如上圖右下角,事實表T1 left join 維表T2,根據某個 key 做關聯,然後利用維表的某一個欄位去做過濾。熟悉 Spark或 Trino 的同學應該都知道,這種情況下可以利用dynamic filter來提高過濾效率,表T2,透過f1 過濾出key2, key2 可能是一個值,也可能是有限的幾個值。key2 即是T1表對應的 Key1 的取值,然後將 key1的取值下推到T1事實表中,理想情況下不需要做全表掃描。實際,我們在做SSB測試的時候也發現了一個問題,在這種情況下,可能查詢出來key1是一個很大的範圍,比如是 1 到3000。即便資料檔案做了排序,由於範圍太大,無法達到預想效果。

如何解決以上問題?上圖右上角我們擴充了一種 SQL 語法,在事實表上透過關聯維表加了一個維表欄位。關聯關係透過 left join 去關聯維表,這裡有限制條件unique,也可以支援primary key。 中間 SQL 語句:可以透過新增維表欄位 F1作排序,對應的Iceberg後設資料,索引每個檔案的Min/Max 值。查詢時,可以將F1 欄位直接下推到事實表,如左圖2,這種情況下只需要讀一個檔案就可以。

預計算主要解決聚合、多表關聯場景下大量資料攝入、計算密集導致查詢耗時的問題。目前我們實現了單表、多表的預計算,支援多種聚合函式:count、avg、max、min、sum、count_distinct、approx_count_distinct、percentile、top_n,支援查詢部分 cube 檔案、部分資料檔案的場景,計算引擎在 Plan 階段 透過 iceberg 後設資料,判斷查詢是否能命中預計算,並進行相應的查詢改寫。

透過SSB 1000 1TB資料查詢測試,整體效能有幾倍到幾十倍的效能提升。

第二部分,總結來看,核心最佳化核心是,只讀取查詢所需的資料,儘量減少無用資料的攝入。

智慧化管理平臺 Magnus

Magnus 背景:

Iceberg 是一個表格式,只提供了資料、後設資料讀、寫 API 的實現,缺乏統一的資料、後設資料操作、管理的服務。另外我們引入Iceberg 是為了替換Hive,使用者習慣了使用 Hive 表,怎麼減少使用者使用 Iceberg 表的成本?使得使用起來跟普通的 Hive 表一樣?

上圖是我們資料平臺使用者建表的一個截圖,截圖部分是建 Iceberg 表比建普通的Hive表要多出來的一部分。需要使用者去填資料分佈資訊,以及資料索引的配置資訊。這對使用者而言會產生一些問題。首先,可能使用者都不確定常用查詢Pattern是什麼樣的,其次,使用者對如何定義資料分佈,如何定義索引會有一定的學習和理解成本。還有一種情況,由於查詢模式會隨時間變化,需要使用者頻繁去改動,或者使用者可能根本未感知到變化,這會導致隨時間查詢效能逐步下降。另外,上文我們提到的資料組織排序、索引,都只介紹了其定義,並未涉及這些操作是該由誰來觸發,交由誰來管理,顯然直接交給使用者是不合理的。

為了解決上面提到的一些問題,我們開發了智慧化管理平臺 Magnus。其架構如下:

Magnus包括後設資料管理、最佳化結果以及最佳化推薦三部分。同時Magnus 會去監聽Spark 、Flink、 API ETL 等作業的 Commit Event,Commit Event的資訊會包含具體是哪一個表、哪個快照操作,操作型別,這些資訊都會通知到Magnus。Magnus透過查詢HDFS的後設資料瞭解表上有沒有定義對應的組織排序、索引等資訊,生成後續的操作,對應操作會先落庫到資料庫裡面,待達到相應條件,觸發具體的作業執行。

目前支援的作業型別包括Optimized Action(包括對資料進行小檔案合併、組織排序等)、構建索引、生成cube、重寫後設資料(如果後設資料都很小,源資料的讀取開銷不能忽略,這種情況下可以進行後設資料重寫、合併),此外,還支援快照過期、孤兒檔案刪除,索引和 cube 刪除等,相應的 作業 會使用 Spark 進行執行。

上圖為Magnus Iceberg後設資料管理平臺的介面,包括某個表的快照、manifest、分割槽統計資訊等,以及表的列資訊,包括關聯列、索引、cube 資訊等。此外,還有最佳化彙總的資訊以及分析模組推薦等。

上圖為Magnus智慧化資料組織最佳化的流程,待執行任務,會先落地到DB,Magnus的排程任務會把它撈出來準備做提交,提交之前會有一些操作。首先看具體是哪個表,要做什麼樣的操作,是做組織排序還是建索引或其他操作,根據具體操作統計影響分割槽檔案的大小,進行Spark 資源的分配。關於Resource Limit ,由於我們 Iceberg 表資料存在獨立的Hadoop叢集,如果白天有很多ETL任務對整個查詢效能會有很大影響,所以透過Resource Limit 去限制白天跑的整體任務量,儘量不要去影響Ad Hoc查詢。

如果資源達到或超過了設定的最大值,會把 Job 加入等待佇列。針對資料可能存在不同的機房,透過分割槽資料進行探測,獲取資料所在機房,並提交到指定的 Yarn Queue,實現多機房之間的排程,最終所有 spark job 透過 Yarn-Cluster模式進行排程執行。

上圖為Magnus的智慧查詢分析與最佳化模式推薦,右邊是Magnus,左邊是計算引擎Trino,使用者的 SQL 提交到 Trino引擎後,Trino會將能下推到儲存的過濾條件解析出來。我們會將每個SQL的Query資訊以及能夠下推的過濾條件,都儲存到 MySQL。

Magnus每天會去抽取歷史的查詢資訊進行分析,分析包括:過濾的條件、條件欄位所在表對應的最細粒度分割槽的基數,分割槽資料檔案大小以及分割槽定義,也會去看對應的查詢過濾欄位出現的頻率。如果是組合查詢,會對組合頻率進行統計,並區分是點查還是範圍查詢,以及查詢耗時等統計資訊,最終我們會把這些統計資訊彙總重新落地到 MySQL。上圖Magnus 右側是一個推薦模組,推薦模組會分析彙總的資訊,其中涉及一些規則:首先是預設邊界的檢測:比如檢測是不是小表,如果表的單分割槽記錄數只有百萬級別或更少,大機率它只會生成一個檔案,如果再去進行Z-order排序是沒有意義的。核心點,會對不同的影響因子設定權重、提供一套統一的經驗公式。影響因子包括:過濾欄位的基數、過濾百分比、查詢頻次、查詢耗時等,最終為每個表推薦出更合理的分割槽設定、組織排序欄位、索引資訊、其他Trait等資訊。

如上圖,是作出推薦結果的依據,統計資訊包括每個欄位的查詢頻次,是等值過濾還是範圍查詢,欄位的的基數、不同欄位組合查詢的耗時等,據此可以推斷推薦結果是否合理。

第三部分:總結來看,Magnus 的核心價值就是助力查詢加速,降低使用者使用湖倉的門檻。

未來規劃

我們近期在湖滄一體方向上的規劃主要有以下幾個方面:一、預計算支援Star Tree,主要是解決維度欄位基數過高導致效能衰退的問題。二、歷史分析推薦支援預計算。三、歷史分析推薦實現真正的智慧化, Magnus 的定位是智慧化的,但是目前離智慧化還有一段距離,推薦結果出來之後,還是需要人工進行推薦結果的應用以及效果的驗證對比,未來我們希望能做到不需要人工的參與。四、CDC 資料落地支援,後面會推進更多CDC業務場景的落地。

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

相關文章