物化視圖在 MaxCompute 中的探索與實踐
一、MaxCompute 和物化視圖
MaxCompute 是一個多功能、高性能、易使用的企業級的數據倉庫服務,已經為阿里巴巴集團提供服務達 14 年。目前每日 DML 的任務數超過了 2,600 萬,單日的數據量規模達到 EB 級,服務集團內用戶 4W+。在如此大的體量之下,也暴露出幾個問題:隨著業務的規模越來越大,重復計算越來越多,消耗了大量資源;對于計算結果的產出時效有了更高要求;通過大批量改造腳本來進行數據治理的成本高,難度大。最終物化視圖成為解決以上問題的最佳方案。
與普通視圖(Virtual View)不同,物化視圖存儲的是查詢結果的物理副本,而普通視圖僅僅是一個虛擬的表,它在查詢時才動態地生成結果。物化視圖的發展歷史與數據庫技術的進步緊密相關。以下是物化視圖發展的一些關鍵階段。
- 早期數據庫階段:早期的數據庫系統中,并沒有物化視圖的概念。數據庫主要關注于數據的存儲和基本的查詢操作。
- RDBMS 視圖階段:視圖允許用戶通過 SQL 語句定義一個虛擬表,這個虛擬表是基于一個或多個實際表的查詢結果。然而,早期的視圖通常是非物化的,即它們在查詢時才計算結果。
- RDBMS 物化視圖階段:物化視圖的概念在 20 世紀 90 年代初期被提出。物化視圖將查詢結果實際存儲在數據庫中,這樣用戶就可以像訪問普通表一樣訪問物化視圖,而不需要每次都執行復雜的查詢。隨著數據庫技術的發展,物化視圖的性能優化和自動化管理成為研究的重點。數據庫管理系統(DBMS)提供了更多的功能來優化物化視圖的性能,如增量更新、自動更新、并行處理等。
- 云原生大數據物化視圖階段:在云計算和大數據時代,物化視圖的作用變得更加重要和普遍。基于云計算幾乎無限的可擴展性,物化視圖可以適應更大的數據集;實時計算引擎提高了物化視圖的更新頻率和更新效率;自動化和編排工具使得物化視圖的創建、管理和刷新變得簡單;云計算通常是按需付費模式,物化視圖節約了計算資源,實現降本增效;物化視圖可以作為數據質量的檢查點,監控數據質量。
物化視圖的優點如下:
- 提高查詢性能:對于復雜的查詢,由于物化視圖存儲了查詢結果,對于頻繁執行的查詢,可以直接從物化視圖中讀取數據,而不需要每次都執行完整的查詢,從而提高了查詢效率。
- 保持數據一致性:物化視圖可以定期刷新,以確保數據的一致性。在數據變化不頻繁的情況下,這可以減少數據同步的開銷。
- 應急查詢:物化視圖允許用戶在數據庫服務器關閉或網絡連接中斷時,仍然可以訪問和分析數據。
物化視圖也有一些缺點:
- 存儲空間:物化視圖需要額外的存儲空間來保存查詢結果。
- 數據更新:如果底層數據頻繁變動,物化視圖需要定期刷新,這可能會增加維護成本。
- 復雜性:對于某些復雜的查詢,物化視圖可能難以實現或者維護。
二、物化視圖的設計和實現
在物化視圖的設計階段,我們關注物化視圖的創建、維護和應用。
1. 如何創建物化視圖
MaxCompute 支持創建普通物化視圖、分區物化視圖、聚簇物化視圖和穿透物化視圖,具體的創建方式體現在建表語句中,PARTITIONED BY (col_name) 語句指定創建物化視圖表為分區表,CLUSTERED BY (col_name) SORTED BY (col_name [ASC | DESC])INTO number_of_buckets BUCKETS 語句指定創建物化視圖為聚簇表。
在物化視圖創建的過程中有兩個關鍵點,第一個是需要建立一個基表到物化視圖的索引,這樣在查詢時就能快速地獲取到相關的物化視圖。第二個是基表數據版本保存,在物化視圖的元數據中需要保存對應基表的數據版本;另外對于分區物化視圖,要求分區物化視圖的分區列和基表保持一致,這樣的話,可以實現分區級的增量更新。
2. 如何維護物化視圖
MaxCompute 通過建表語句中的 TBLPROPERTIES 指定是否開啟自動刷新,刷新時間間隔和分區增量刷新:
- "enable_auto_substitute"="true", --指定當分區不存在時是否轉化視圖來查詢。
- "enable_auto_refresh"="true", --指定是否開啟自動刷新。
- "refresh_interval_minutes"="120", --指定刷新時間間隔。
- "only_refresh_max_pt"="true" --針對分區物化視圖,只自動刷新源表最新分區。
3. 如何使用物化視圖實現加速查詢
自動查詢改寫:自動查詢改寫通過四個步驟實現,第一步,利用基表到 MV 的索引去獲取相關物化視圖;第二步是命中預判定,假如一個基表關聯的 MV 的數目太多的話,通過命中預判定,以便盡早過濾無效的物化視圖;第三步是把物化視圖注冊到優化器中;第四步是改寫校驗及執行,這主要包括的是基于 CALCITE 改寫規則的二次開發,其中包含了一系列的校驗,包括字段校驗、謂詞校驗、關聯校驗以及分組和聚合校驗等,通過這些校驗來判斷查詢字段、查詢條件、關聯條件、分組和聚合條件等是否與物化視圖一致,從而決定是否能用物化視圖改寫查詢。
比如一個查詢 SQL 是:
SELECT ds, count(uid) as pv
FROM users
WHERE ds>=‘20230501’ AND ds<=‘20230507’
GROUP BY ds;
物化視圖為:
SELECT ds, count(uid) as pv
FROM users
WHERE ds>=‘20230401’
GROUP BY ds;
查詢改寫后的 SQL 就變成了:
SELECT ds, pv
FROM mv
WHERE ds>=‘20230501’ AND ds<=‘20230507’ ;
自動查詢改寫是基于 SPJG 的匹配。匹配會自動忽略空格、換行、注釋、別名等影響,除此之外查詢 SQL 與物化視圖 SQL 不完全相同的場景下,自動查詢改寫會嘗試改寫查詢 SQL,補償物化視圖 SQL 和查詢 SQL 之間缺少的計算動作,比如當 SQL 查詢的 SELECT 列與物化視圖 SQL 的 SELECT 列不完全相同時,自動查詢改寫對 SELECT 列支持情況如下:
- 支持查詢 SQL 的 SELECT 列的順序與物化視圖 SQL 不同。
- 支持物化視圖 SQL 中的 SELECT 列沒有出現在查詢 SQL 中。
- 支持查詢 SQL 中的 SELECT 列不在物化視圖 SQL 的 SELECT 列中,但是可以由物化視圖 SQL 的 SELECT 列組合計算得到。
- 不支持查詢 SQL 中的 SELECT 列不在物化視圖 SQL 的 SELECT 列中,且無法由物化視圖 SQL 的 SELECT 列組合計算得到。
自動穿透:自動穿透的關鍵是區分物化數據和非物化數據。通過 SQL 解析后的執行計劃,確定查詢 SQL 的目標分區,然后去 MV 里面看相應的分區是否得到了物化,如果存在沒有物化的分區,就將該分區轉化為視圖去執行。比如有個查詢 SQL 是:select key from src where ds >= ‘20230530’group by key,存在一個按天增量的 MV 只有 20230601 到 20230605 的數據,自動穿透功能會直接讀取 20230601到 20230605 已物化的分區,并將未物化的分區 20230530 和 20230531 轉化為視圖執行,最后將兩部分數據 UNION ALL 起來。自動穿透既節省了存儲,又實現了靈活擴展。
三、智能推薦及自動物化視圖
物化視圖在推廣的過程中存在以下三個問題:
- 用戶的 SQL 能力有限,對于物化視圖的了解有限,無法很好利用。
- 用戶具備相應 SQL 水平,但是不具備全局視角,無法確定哪些重復計算應該建立物化視圖。
- 不能準確衡量物化視圖的價值,就不具備大規模的宣傳和推廣的動力。
針對以上三個問題,MaxCompute 通過智能推薦和自動物化的方法降低物化視圖的創建難度,提高用戶使用體驗。
1. 智能推薦
通過對執行任務進行分析,智能選擇資源消耗大、任務耗時長、使用頻率高、預期收益大的 SQL 進行語句拆分和合并,提取出公共表達式,基于公共表達式構建物化視圖。在任務運行時選擇匹配率高的物化視圖進行推薦,比如:
- 優先全匹配,當不存在全匹配的物化視圖時才會嘗試選擇需要進行補償的物化視圖。
- 當有多個需要進行補償的物化視圖時,查詢 SQL 涉及的表與物化視圖涉及的表匹配的數量越多,優先級越高。
- 當有多個需要進行補償的物化視圖與查詢 SQL 涉及的表匹配數量相同時,根據物化視圖的數據存儲大小作為優先級標準,物化視圖的數據存儲大小越小,優先級越高。
2. 自動物化視圖
在自動物化視圖的實現中,有三個關鍵點:
- 在線物化,利用延遲物化能力,先不生成數據,等到 SQL 執行時再生成數據。
- QUATA 限制:物化視圖不能沒有限制的隨意生成,我們會敲定一個配額,只有占用存儲在這個閾值之內,才會自動生成物化視圖。
- 收集反饋,根據反饋結果對物化視圖進行迭代,只保留有價值的物化視圖。用戶可在 CONSOLE 頁面,一站式生成和查看物化視圖。
四、總結和展望
MaxCompute 物化視圖的功能概覽如下圖所示:
我們針對業界產品做了一個分析,對比 MaxCompute 與 Hive、Spark、Snowflake、RedShift、BigQuery 等產品的物化視圖功能,如下所示。
可以看到,MaxCompute 中的物化視圖的功能還是很全的,囊括了分區、聚簇、查詢改寫、延時物化、穿透、自動生成和自動更新等功能。
MaxCompute 物化視圖在淘天業務線的應用效果如下:
在淘天業務線上,目前創建了超 5 千個物化視圖,優化的查詢任務超 2 萬。優化后的查詢平均資源的消耗降低了 20% 以上,甚至有一些查詢消耗降低了 80%。目前自動物化視圖這個功能還在灰度中,預計最終可以創建超 10 萬個物化視圖,查詢的覆蓋范圍可以達到 50 萬,預計將節省 14% 的 CU 資源。
最后是對未來工作的展望。
未來,我們還將在以下方面進行完善:
- 增量更新:雖然現在已經實現分區級的增量更新,可以滿足大部分批處理的場景要求,但是對于更新頻率要求更高的場景,更新的粒度還有待細化。
- 基于事件觸發更新:目前支持定時刷新、手動刷新和分區增量刷新,未來希望可以做到基于事件的更新。
- 擴展外表的使用場景:湖倉一體的時代,大量的數據都存儲在 OSS 和 HDFS 上,物化視圖也可以作為一個外部數據的緩存去使用。
- 擴展查詢改寫算子:自動查詢改寫這塊還有很大的擴展空間,比如擴展對 LEFT OUTER/RIGHT OUTER JOIN 的支持,擴展對 GROUP BY、HAVING、ORDER BY、LIMIT 和聚合函數表達式的支持。