本文為您介紹Delta Table在資料群組織最佳化服務上的架構設計。
Clustering
當前痛點
Delta Table支援分鐘級近即時增量資料匯入,高流量情境下可能會導致增量小檔案數量膨脹,從而引發儲存訪問壓力大、成本高,並且大量的小檔案還會引發Meta更新以及分析執行慢,資料讀寫I/O效率低下等問題,因此需要設計合理的小檔案合并服務,即Clustering服務來自動最佳化此類情境。
解決方案
Clustering服務主要由MaxCompute內部的Storage Service來負責執行,專門解決小檔案合并的問題,但它並不會改變任何資料的歷史中間狀態,即不會消除任何一條記錄資料的中間歷史狀態。
Clustering服務流程
Clustering服務的整體操作流程如圖所示。
Clustering策略的制定主要基於典型的讀寫業務情境,會周期性地根據資料檔案的大小、數量等多個維度進行綜合評估,並進行分層次的合并。Level0~Level1階段主要針對原始寫入的DeltaFile(圖中藍色資料檔案)進行合并,形成中等大小的DeltaFile(圖中黃色資料檔案)。當中等大小的DeltaFile達到一定規模後,會進一步觸發Level1~Level2的合并,產生更大的DeltaFile(圖中橙色資料檔案)。
針對超過一定大小的資料檔案,將進行專門的隔離處理,以避免觸發進一步的合并,從而避免不必要的讀寫放大問題。例如:Bucket3的T8資料檔案所示。另外,對於超過一定時間跨度的檔案也不會進行合并,因為將時間跨度太大的資料合併在一起可能導致在進行Time Travel或者增量查詢時讀取大量不屬於此次查詢時間範圍的歷史資料,進而造成不必要的讀放大問題。
由於資料是按照BucketIndex來切分儲存的,因此Clustering服務會以Bucket粒度來並發執行,大幅縮短整體已耗用時間。
Clustering服務會與Meta Service進行互動,以擷取待處理的表或分區列表。完成操作後,會將新舊資料檔案的資訊傳入Meta Service。Meta Service在此過程中起到關鍵作用,它負責進行事務衝突檢測,協調新舊檔案Meta資訊的無縫更新以及安全地回收舊資料檔案。
Clustering服務能有效解決大量檔案引發的讀寫效率低下的問題。由於每次執行至少需要讀寫一遍資料,將會消耗計算和I/O資源,存在一定的讀寫放大問題,當前MaxCompute引擎能夠根據系統狀態自動觸發執行,以確保Clustering服務的高效執行。
Compaction
當前痛點
Delta Table支援Update和Delete格式的資料寫入。如果存在大量此格式的資料寫入,會導致中間狀態的冗餘記錄過多,增加儲存和計算成本,降低查詢效率等問題。因此,需要設計合理的Compaction服務,以消除中間狀態並最佳化這種情境。
解決方案
Compaction服務主要由MaxCompute內部的Storage Service來負責執行,既支援手動執行SQL語句觸發,也可通過配置表屬性按照時間頻率、Commit次數等維度自動觸發。此服務會把選中的資料檔案,包含BaseFile和DeltaFile,一起進行Merge,消除資料的Update和Delete中間狀態,PK值相同的多行記錄只保留最新狀態的一行記錄,最後產生新的只包含Insert格式的BaseFile。
Compaction服務流程
Compaction服務的整體操作流程如下所示。
在t1~t3時間段內,一批DeltaFile被寫入,觸發Compaction操作,以Bucket粒度並發執行,將所有的DeltaFile進行Merge,然後每個Bucket會產生新的BaseFile。隨後在t4和t6時間段,又寫入了一批新的DeltaFile,再次觸發Compaction操作,將當前存在的BaseFile和新增的DeltaFile一起進行Merge操作,重建一個新的BaseFile。
Compaction服務還需要與Meta Service進行互動。其流程與Clustering類似,需要擷取需要執行此操作的表或分區的列表。執行結束後,將新舊資料檔案的資訊傳入Meta Service。其中,Meta Service負責Compaction操作的事務衝突檢測、新舊檔案Meta資訊的原子更新以及舊資料檔案的回收等工作。
Compaction服務通過消除記錄的歷史狀態以節省計算和儲存資源,提升全量快照查詢的效率。然而,頻繁執行Compaction需要大量計算和I/O資源,並可能導致新BaseFile佔用額外儲存,歷史DeltaFile檔案可能會被用於Time Travel查詢,不能立即刪除,將繼續產生儲存成本。因此,應根據具體業務需求和資料特性來決定Compaction操作的執行頻率。在Update和Delete操作頻繁以及全量查詢需求高的情況下,可以考慮增加Compaction的頻率以最佳化查詢速度。
資料回收
由於Time Travel和增量查詢都會查詢資料的歷史狀態,因此需要儲存一定的時間,可通過表屬性acid.data.retain.hours來配置保留的時間範圍。如果歷史狀態資料存在的時間早於配置值,系統會開始自動回收清理,一旦清理完成,Time Travel就查詢不到對應的歷史狀態了。回收的資料主要包含動作記錄和資料檔案兩部分。
同時,也會提供purge命令,用於特殊情境下手動觸發強制清除歷史資料。
需要特別說明的是,對於Delta Table,如果使用者一直寫入新的DeltaFile,那永遠也刪除不了任何一個DeltaFile,因為其他的DeltaFile可能對它有狀態依賴。只有執行COMPACTION或者InsertOverwrite操作後,之後產生的資料檔案對之前的那些DeltaFile就沒有依賴了,如果超過Time Traval可查詢的時間周期後,就可以被刪除了。
對於使用者就是一直不執行Compaction操作的極端情境,引擎側會做一些最佳化避免產生無限的記錄,後台系統會周期性地對超過Time Travel時間的BaseFile或者DeltaFile進行自動Compaction,後續就可以正常回收這些被Compaction的歷史資料檔案。