本文將介紹如何利用Spark執行儲存治理任務,清理孤立檔案、到期快照以及合并小檔案,可以有效降低儲存成本並提升查詢效能。
前提條件
請先根據需求完成Catalog授權:
下載依賴配置
依賴配置
Serverless Spark
將四個依賴包上傳到OSS,並在session中添加額外的Spark 配置。
spark.emr.serverless.excludedModules:固定值為iceberg。spark.emr.serverless.user.defined.jars:實際JAR包的存放路徑。
spark.emr.serverless.excludedModules iceberg
spark.emr.serverless.user.defined.jars oss://${bucket}/iceberg-spark-runtime-3.5_2.12-1.10.1.jar,oss://${bucket}/iceberg-aws-bundle-1.10.1.jar,oss://${bucket}/bennett-iceberg-plugin-2.8.0.jar,oss://${bucket}/guava-31.1-jre.jarSpark Procedures
Iceberg 提供了多種 Spark 預存程序用於表維護。您可以通過 CALL 文法直接在 Spark SQL 中執行這些操作。
清理孤立檔案 (Remove Orphan Files)
孤立檔案是指不再被任何 Iceberg 表中繼資料(Metadata)引用的物理檔案。這些檔案通常產生於刪除表操作或失敗的 ETL 任務中。定期清理孤立檔案是釋放儲存空間的關鍵步驟。
說明
只需替換table參數的值為實際庫表名,如未備忘,無需替換。
-- 1. 幹運行模式 (Dry Run)
-- 僅列出將被刪除的檔案,不執行實際刪除。用於確認清理範圍。
CALL iceberg_catalog.system.remove_orphan_files(
table => 'db.table_name',
prefix_listing => true, --使用Object Storage Service的首碼列表功能。這能顯著提高在OSS/S3等Object Storage Service上的掃描效能。
dry_run => true --僅類比執行並返回擬刪除檔案清單。
);
-- 2. 預設清理
-- 刪除 3 天前產生的孤立檔案。
CALL iceberg_catalog.system.remove_orphan_files(
table => 'db.table_name',
prefix_listing => true
);
-- 3. 指定時間與並發
-- 刪除指定時間戳記之前的孤立檔案,並開啟並行刪除。
CALL iceberg_catalog.system.remove_orphan_files(
table => 'db.table_name',
older_than => TIMESTAMP '2024-01-01 00:00:00', --替換指定時間
dry_run => false,
max_concurrent_deletes => 4, --執行檔案刪除操作的並發線程數。
prefix_listing => true
);更多詳情請參閱 Iceberg Remove Orphan Files。
清理到期快照 (Expire Snapshots)
Iceberg 通過快照(Snapshots)跟蹤表的所有變更歷史。隨著時間推移,過多的快照會導致中繼資料膨脹並佔用大量儲存空間。該過程用於刪除不再需要的舊快照及其關聯的資料檔案。
-- 1. 基於時間清理
-- 刪除早於指定時間戳記的快照。
CALL iceberg_catalog.system.expire_snapshots(
table => 'db.table_name',
older_than => TIMESTAMP '2024-01-01 00:00:00' --替換指定時間
);
-- 2. 保留最新快照
-- 無論時間如何,始終保留最近的 N 個快照。
CALL iceberg_catalog.system.expire_snapshots(
table => 'db.table_name',
retain_last => 5
);
-- 3. 刪除特定快照
-- 僅刪除 ID 列表中指定的快照。
CALL iceberg_catalog.system.expire_snapshots(
table => 'db.table_name',
snapshot_ids => ARRAY(123456789, 987654321) --替換指定ID
);更多詳情請參閱Iceberg Expire Snapshots
合并小檔案 (Rewrite Data Files)
頻繁的小批量寫入會產生大量小檔案,嚴重影響讀取效能。該過程通過重寫資料檔案,將其合并為符合目標大小的較大檔案,從而最佳化查詢效率。
-- 1. 預設合并
-- 使用預設的 binpack 策略合并檔案。
CALL iceberg_catalog.system.rewrite_data_files('db.table_name');
-- 2. 指定 Binpack 策略(通過簡單的裝箱演算法將小檔案合并為大檔案,開銷最小,速度最快)
CALL iceberg_catalog.system.rewrite_data_files(
table => 'db.table_name',
strategy => 'binpack'
);
-- 3. 帶過濾條件的合并
-- 僅重寫符合特定分區或條件的資料。
CALL iceberg_catalog.system.rewrite_data_files(
table => 'db.table_name',
where => 'date >= "2024-01-01"' --date為表中實際欄位名,請根據實際修改過濾條件。
);
-- 4. 自訂檔案大小選項
-- 顯式設定目標檔案大小 (512MB) 和最小合并閾值 (128MB)。
CALL iceberg_catalog.system.rewrite_data_files(
table => 'db.table_name',
options => map(
'target-file-size-bytes', '536870912',
'min-file-size-bytes', '134217728'
)
);更多詳情請參閱Iceberg Rewrite Data Files。