StarRocks 物化視圖創(chuàng)建與刷新全流程解析
最近在為 StarRocks 的物化視圖增加多表達(dá)式支持[1]的能力,于是便把物化視圖(MV)的創(chuàng)建刷新流程完成的捋了一遍。
這次從頭開始,從 MV 的創(chuàng)建開始來看看 StarRocks 是如何管理物化視圖的。
創(chuàng)建物化視圖
CREATE
MATERIALIZED VIEW mv_test99
REFRESH ASYNC EVERY(INTERVAL 60 MINUTE)
PARTITION BY p_time
PROPERTIES (
"partition_refresh_number" = "1"
)
AS
select date_trunc("day", a.datekey) as p_time, sum(a.v1) as value
from par_tbl1 a
group by p_time, a.item_id創(chuàng)建物化視圖的時(shí)候首先會(huì)進(jìn)入這個(gè)函數(shù):com.starrocks.sql.analyzer.MaterializedViewAnalyzer.MaterializedViewAnalyzerVisitor#visitCreateMaterializedViewStatement
圖片
其實(shí)就是將我們的創(chuàng)建語句結(jié)構(gòu)化為一個(gè)
CreateMaterializedViewStatement對(duì)象,這個(gè)過程是使用 ANTLR 實(shí)現(xiàn)的。
這個(gè)函數(shù)負(fù)責(zé)對(duì)創(chuàng)建物化視圖的 SQL 語句進(jìn)行語義分析、和基本的校驗(yàn)。
比如:
? 分區(qū)表達(dá)式是否正確
? 基表、數(shù)據(jù)庫(kù)這些的格是否正確
圖片
校驗(yàn)分區(qū)分區(qū)表達(dá)式的各種信息。
然后會(huì)進(jìn)入函數(shù):com.starrocks.server.LocalMetastore#createMaterializedView()
這個(gè)函數(shù)的主要作用如下:
1. 檢查數(shù)據(jù)庫(kù)和物化視圖是否存在。
2. 初始化物化視圖的基本信息:
? 獲取物化視圖的列定義(schema)
? 驗(yàn)證列定義的合法性
? 初始化物化視圖的屬性(如分區(qū)信息)。
3. 處理刷新策略:
? 根據(jù)刷新類型(如 ASYNC、SYNC、MANUAL 或 INCREMENTAL)設(shè)置刷新方案。
? 對(duì)于異步刷新,設(shè)置刷新間隔、開始時(shí)間等,并進(jìn)行參數(shù)校驗(yàn)。
4. 創(chuàng)建物化視圖對(duì)象:
? 根據(jù)運(yùn)行模式(存算分離和存算一體)創(chuàng)建不同類型的物化視圖對(duì)象
? 設(shè)置物化視圖的索引、排序鍵、注釋、基礎(chǔ)表信息等。
5. 處理分區(qū)邏輯:
? 如果物化視圖是非分區(qū)的,創(chuàng)建單一分區(qū)并設(shè)置相關(guān)屬性。
? 如果是分區(qū)的,解析分區(qū)表達(dá)式并生成分區(qū)映射關(guān)系
6. 綁定存儲(chǔ)卷:
? 如果物化視圖是云原生類型,綁定存儲(chǔ)卷。
圖片
序列化關(guān)鍵數(shù)據(jù)
對(duì)于一些核心數(shù)據(jù),比如分區(qū)表達(dá)式、原始的創(chuàng)建 SQL 等,需要再重啟的時(shí)候可以再次加載到內(nèi)存里供后續(xù)使用時(shí);
就需要將這些數(shù)據(jù)序列化到元數(shù)據(jù)里。
這些數(shù)據(jù)定期保存在fe/meta目錄中。
圖片
我們需要序列化的字段需要使用 @SerializedName注解。
@SerializedName(value = "partitionExprMaps")  
private Map<ExpressionSerializedObject, ExpressionSerializedObject> serializedPartitionExprMaps;同時(shí)在 com.starrocks.catalog.MaterializedView#gsonPreProcess/gsonPostProcess 這兩個(gè)函數(shù)中將數(shù)據(jù)序列化和反序列化。
元數(shù)據(jù)的同步與加載
當(dāng) StarRocks 的 FE 集群部署時(shí),會(huì)由 leader 的 FE 啟動(dòng)一個(gè) checkpoint 線程,定時(shí)掃描當(dāng)前的元數(shù)據(jù)是否需要生成一個(gè) image.${JournalId} 的文件。
圖片
其實(shí)就是判斷當(dāng)前日志數(shù)量是否達(dá)到上限(默認(rèn)是 5w)生成一次。
具體的流程如下:
圖片
圖片
更多元數(shù)據(jù)同步和加載流程可以查看我之前的文章:深入理解 StarRocks 的元數(shù)據(jù)管理[3]
刷新物化視圖
創(chuàng)建完成后會(huì)立即觸發(fā)一次 MV 的刷新邏輯。
同步分區(qū)
圖片
刷新 MV 的時(shí)候有一個(gè)很重要的步驟:同步 MV 和基表的分區(qū)。
這個(gè)步驟在每次刷新的時(shí)候都會(huì)做,只是如果基表分區(qū)和 MV 相比沒有變化的話就會(huì)跳過。
這里我們以常用的 Range 分區(qū)為例,核心的函數(shù)為:com.starrocks.scheduler.mv.MVPCTRefreshRangePartitioner#syncAddOrDropPartitions
它的主要作用是同步物化視圖的分區(qū),添加、刪除分區(qū)來保持 MV 的分區(qū)與基礎(chǔ)表的分區(qū)一致;核心流程:
1. 計(jì)算分區(qū)差異:根據(jù)指定的分區(qū)范圍,計(jì)算物化視圖與基礎(chǔ)表之間的分區(qū)差異。
2. 同步分區(qū):
刪除舊分區(qū):刪除物化視圖中與基礎(chǔ)表不再匹配的分區(qū)。
添加新分區(qū):根據(jù)計(jì)算出的差異,添加新的分區(qū)到物化視圖。
圖片
分區(qū)同步完成之后就可以計(jì)算需要刷新的分區(qū)了:
image.png
以上內(nèi)容再結(jié)合之前的兩篇文章:
? 深入理解 StarRocks 的元數(shù)據(jù)管理[5]
就可以將整個(gè)物化視圖的創(chuàng)建與刷新的核心流程掌握了。
引用鏈接
[1] 多表達(dá)式支持: https://github.com/StarRocks/starrocks/pull/60035
[2] StarRocks 物化視圖刷新流程和原理: https://crossoverjie.top/2024/11/18/ob/StarRocks-MV-refresh-Principle/
[3] 深入理解 StarRocks 的元數(shù)據(jù)管理: https://crossoverjie.top/2024/11/11/ob/StarRocks-meta/
[4] StarRocks 物化視圖刷新流程和原理: https://crossoverjie.top/2024/11/18/ob/StarRocks-MV-refresh-Principle/
[5] 深入理解 StarRocks 的元數(shù)據(jù)管理: https://crossoverjie.top/2024/11/11/ob/StarRocks-meta/















 
 
 







 
 
 
 