通過Spark SQL讀寫Iceberg外表
AnalyticDB for MySQL支援通過Spark SQL建立、讀寫和管理Iceberg外表。Spark 3.5及以上版本預設內建Iceberg讀寫能力,無需額外配置即可使用。本文介紹如何選擇Catalog模式管理Iceberg表中繼資料,以及如何完成Iceberg外表的建立、讀寫、查詢和刪除操作。
前提條件
叢集的產品系列為企業版、基礎版或湖倉版。
企業版和基礎版預留資源需大於0 ACU。
湖倉版叢集儲存預留資源需大於0 ACU。
叢集核心版本需為3.2.5.0及以上版本。
說明請在雲原生資料倉儲AnalyticDB MySQL控制台集群信息頁面,配寘資訊地區,查看和升級核心版本。
已建立資料庫帳號。
如果是通過阿里雲帳號訪問,只需建立高許可權帳號。
如果是通過RAM使用者訪問,需要建立高許可權帳號和普通帳號並且將RAM使用者綁定到普通帳號上。
叢集與OSS儲存空間位於相同地區。
如需使用湖儲存模式,需已開通湖儲存。
Catalog模式說明
Spark讀寫Iceberg外表時,需要通過Catalog管理表的中繼資料。AnalyticDB for MySQL支援以下三種Catalog模式:
Catalog模式 | 說明 | 是否需要額外配置 | 適用情境 |
MDS Catalog(預設) | 基於AnalyticDB for MySQL內建中繼資料服務(MDS)管理Iceberg表中繼資料。 | 不需要,開箱即用。 | 僅在AnalyticDB for MySQL內部使用Spark讀寫Iceberg表。 |
Hadoop Catalog | 基於Hadoop檔案系統管理Iceberg表中繼資料,中繼資料以檔案形式儲存在指定的OSS路徑下。 | 需要配置 | 需要跨產品協同讀寫同一張表,例如EMR Spark、Flink等。 |
湖儲存 | 基於AnalyticDB for MySQL湖儲存管理Iceberg表,底層使用Hadoop Catalog,由系統自動管理儲存路徑。 | 需要開啟 | 湖倉版叢集使用湖儲存功能。 |
如何選擇Catalog模式
僅在AnalyticDB for MySQL內部使用:三種模式均可,推薦使用湖儲存模式(若已開通湖儲存)或預設的MDS Catalog模式,配置最簡單。
需要跨產品協同讀寫同一張表(例如EMR Spark寫入後由AnalyticDB for MySQL查詢,或Flink寫入後由Spark查詢):建議使用Hadoop Catalog或湖儲存模式。不同Catalog模式的中繼資料相互獨立,跨模式混合寫入同一張表會導致中繼資料不一致,詳情請參見注意事項。
表名引用方式
AnalyticDB for MySQL支援以下兩種方式引用Iceberg表:
兩層結構(推薦):
資料庫名.表名,例如my_db.my_table。系統會自動識別表類型並路由到對應的Iceberg Catalog,無需指定Catalog名稱。三層結構:
Catalog名.資料庫名.表名,例如iceberg.my_db.my_table。適用於需要明確指定Catalog的情境。
Spark 3.5及以上版本中,系統自動註冊了以下Iceberg Catalog名稱:
Catalog名稱 | 說明 |
| 預設的Iceberg Catalog名稱。 |
| Iceberg Catalog的簡便別名,與 |
樣本(以下三種寫法等價)
SELECT * FROM my_db.my_table;
SELECT * FROM iceberg.my_db.my_table;
SELECT * FROM adb_lakehouse_prod.my_db.my_table;操作步驟
步驟一:進入資料開發
登入雲原生資料倉儲AnalyticDB MySQL控制台,在左上方選擇叢集所在地區。在左側導覽列,單擊集群清單,然後單擊目的地組群ID。
配置Spark參數。
根據所選的Catalog模式,需要配置不同模式的SET參數:
Catalog模式
SET參數
MDS Catalog(預設)
SET spark.adb.version=3.5;Hadoop Catalog
SET spark.adb.version=3.5;SET spark.iceberg.warehouse=oss://testBucketName/iceberg/;湖儲存
SET spark.adb.lakehouse.enabled=true;SET參數的配置方式因資源群組類型而異:
Job型資源群組 :直接將SET語句寫在SQL語句前面即可。如本文後續SQL樣本所示。
Interactive型資源群組 :需要將Spark參數預先配置到資源群組中。配置完成後,SQL語句中無需再添加對應的SET語句。
在左側導覽列單擊。
在目標資源群組所在行操作列,單擊修改。
在修改資源組面板中更新Spark 配置,然後單擊確定。
當資源群組狀態變為運行中時,修改生效。
在左側導覽列,單擊。
在SQLConsole視窗,選擇Spark引擎和資源群組(Job型資源群組或Spark引擎的Interactive型資源群組)。
步驟二:建立外庫與Iceberg外表
請根據所選的Catalog模式,按照對應方式建立外庫和Iceberg外表。
MDS Catalog模式(預設)
Spark 3.5及以上版本預設內建Iceberg Catalog支援。MDS Catalog模式下,中繼資料由AnalyticDB for MySQL MDS自動管理,無需配置spark.iceberg.warehouse等Catalog參數,但需要指定資料的儲存位置(LOCATION)。
建立外庫
您可以在建立資料庫時通過
LOCATION指定預設的資料存放區路徑。指定後,該資料庫下所有表將自動繼承此路徑。SET spark.adb.version=3.5; CREATE DATABASE adb_iceberg_db LOCATION 'oss://your-bucket/iceberg/';您也可以建立不帶
LOCATION的資料庫。此時需要在建表時為每張表單獨指定LOCATION。CREATE DATABASE adb_iceberg_db;
建立Iceberg外表
SET spark.adb.version=3.5; -- 若資料庫已指定LOCATION,建表時無需再指定 CREATE TABLE adb_iceberg_db.test_iceberg_tbl ( `id` int, `name` string, `age` int ) USING iceberg PARTITIONED BY (age); -- 若資料庫未指定LOCATION,建表時需通過LOCATION指定資料存放區路徑 CREATE TABLE adb_iceberg_db.test_iceberg_tbl ( `id` int, `name` string, `age` int ) USING iceberg PARTITIONED BY (age) LOCATION 'oss://your-bucket/iceberg/test_iceberg_tbl';
Hadoop Catalog模式
如需與其他引擎或產品(如EMR Spark、Flink等)共同讀寫同一張Iceberg表,建議使用Hadoop Catalog模式並指定OSS warehouse路徑,具體配置請參見SET參數配置。
建立外庫前的檢查
如需使用已有資料庫,請通過
DESCRIBE DATABASE查看資料庫DDL,確認滿足以下條件之一:DDL中未指定
Location。DDL中指定了
Location,且Catalog參數值為mix。
如不滿足上述條件,請建立資料庫。
建立外庫
CREATE DATABASE adb_external_db_iceberg;重要如果資料庫指定了
Location,請確保spark.iceberg.warehouse參數指定的OSS路徑首碼與Location保持一致。建立Iceberg外表
SET spark.adb.version=3.5; -- 指定Spark引擎大版本 SET spark.iceberg.warehouse=oss://testBucketName/iceberg/; -- Iceberg外表中繼資料與資料檔案的儲存路徑 CREATE TABLE adb_external_db_iceberg.test_iceberg_tbl ( `id` int, `name` string, `age` int ) USING iceberg PARTITIONED BY (age);
湖儲存模式
湖倉版叢集支援通過湖儲存模式建立和管理Iceberg表。湖儲存模式底層使用Hadoop Catalog,由AnalyticDB for MySQL自動管理資料存放區路徑。
建立外庫
CREATE DATABASE adb_external_db_iceberg WITH DBPROPERTIES ( 'adb_lake_bucket' = 'adb-lake-cn-shanghai-6gml****' );adb_lake_bucket:非必須。指定湖儲存表資料的儲存位置。在資料庫層級指定後,該資料庫下所有表預設使用此湖儲存空間。您也可以在建表時單獨指定,表層級配置優先於資料庫層級。建立Iceberg外表
SET spark.adb.lakehouse.enabled=true; -- 開啟湖儲存 CREATE TABLE adb_external_db_iceberg.test_iceberg_tbl ( `id` int, `name` string, `age` int ) USING iceberg PARTITIONED BY (age) TBLPROPERTIES ( 'adb_lake_bucket' = 'adb-lake-cn-shanghai-6gml****' );
步驟三:寫入或刪除Iceberg外表資料
以下樣本以MDS Catalog模式為主進行說明。
寫入資料
INSERT INTO(追加寫入)
SET spark.adb.version=3.5; INSERT INTO adb_iceberg_db.test_iceberg_tbl VALUES (1, 'lisa', 10), (2, 'jams', 20);INSERT OVERWRITE(全量覆蓋寫入)
INSERT OVERWRITE adb_iceberg_db.test_iceberg_tbl VALUES (1, 'lisa', 10), (2, 'jams', 30);INSERT OVERWRITE靜態分區寫入
僅覆蓋指定分區的資料,其他分區不受影響。
INSERT OVERWRITE adb_iceberg_db.test_iceberg_tbl PARTITION(age=10) VALUES (1, 'anna');INSERT OVERWRITE動態分區寫入
僅覆蓋寫入資料所涉及的分區,其他分區不受影響。
重要如未設定
spark.sql.sources.partitionOverwriteMode=dynamic,INSERT OVERWRITE將覆蓋全表資料,而非僅覆蓋目標資料分割。SET spark.sql.sources.partitionOverwriteMode=dynamic; -- 開啟動態分區覆蓋模式 INSERT OVERWRITE adb_iceberg_db.test_iceberg_tbl PARTITION(age) VALUES (1, 'bom', 10);UPDATE(條件更新)
UPDATE adb_iceberg_db.test_iceberg_tbl SET name = 'box' WHERE id = 2;
刪除資料
DELETE FROM adb_iceberg_db.test_iceberg_tbl
WHERE id = 1;
DELETE FROM adb_iceberg_db.test_iceberg_tbl
WHERE age = 20;步驟四:查詢Iceberg外表資料
SET spark.adb.version=3.5;
SELECT * FROM adb_iceberg_db.test_iceberg_tbl;返回樣本
+---+----+---+
|id |name|age|
+---+----+---+
|2 |box|30 |
+---+----+---+步驟五:刪除Iceberg外表
MDS Catalog模式
SET spark.adb.version=3.5;
-- 僅刪除表的中繼資料,不刪除底層資料檔案
DROP TABLE adb_iceberg_db.test_iceberg_tbl;
-- 同時刪除表的中繼資料和底層資料檔案
DROP TABLE adb_iceberg_db.test_iceberg_tbl PURGE;Hadoop Catalog模式
SET spark.adb.version=3.5;
DROP TABLE adb_iceberg_db.test_iceberg_tbl;湖儲存模式
SET spark.adb.lakehouse.enabled=true;
DROP TABLE adb_external_db_iceberg.test_iceberg_tbl;湖儲存模式下,DROP TABLE僅刪除表的中繼資料,不支援通過PURGE關鍵字刪除底層資料檔案,資料會由AnalyticDB for MySQL的表資源回收筒延遲刪除。
進階功能:中繼資料查詢與預存程序
Iceberg提供了中繼資料表查詢和預存程序(Procedure)能力,用於表維護和中繼資料分析。
中繼資料表查詢和預存程序的調用與普通讀寫遵循相同的Catalog配置規則。使用兩層結構(db.table)時,系統會自動路由到對應Catalog,無需額外配置;使用三層結構時需指定Catalog名稱。對於通過Hadoop Catalog或湖儲存模式建立的表,還需配置對應的SET參數(如spark.iceberg.warehouse或spark.adb.lakehouse.enabled)。
查詢中繼資料表
Iceberg為每張表自動維護了多種中繼資料表,您可以通過表名.中繼資料表名的方式進行查詢。
SET spark.adb.version=3.5;
-- 查看錶的快照資訊(快照ID、時間戳記、操作類型等)
SELECT * FROM adb_iceberg_db.test_iceberg_tbl.snapshots;
-- 查看錶的變更歷史
SELECT * FROM adb_iceberg_db.test_iceberg_tbl.history;
-- 查看當前快照中的資料檔案資訊
SELECT * FROM adb_iceberg_db.test_iceberg_tbl.files;
-- 查看manifest條目(每個檔案的詳細引用資訊)
SELECT * FROM adb_iceberg_db.test_iceberg_tbl.entries;
-- 查看分區統計資訊(記錄數、檔案數等)
SELECT * FROM adb_iceberg_db.test_iceberg_tbl.partitions;常用的中繼資料表包括snapshots、history、files、manifests、entries、partitions和refs等。此外,以all_為首碼的中繼資料表(如all_data_files、all_manifests、all_entries)可查看包含歷史快照在內的全量資訊。完整列表請參見Apache Iceberg官方文檔。
使用預存程序(Procedure)
您可以通過CALL語句調用預存程序進行表維護。
-- 兩層結構:直接使用system命名空間
CALL system.procedure_name('資料庫名.表名', 其他參數...);
-- 三層結構:需加上Catalog名首碼
CALL iceberg.system.procedure_name('資料庫名.表名', 其他參數...);以下是常用的表維護操作樣本。
合并小檔案(rewrite_data_files)
SET spark.adb.version=3.5; -- 使用預設binpack策略合并小檔案 CALL system.rewrite_data_files('adb_iceberg_db.test_iceberg_tbl'); -- 使用sort策略並指定排序欄位,僅對指定分區生效 CALL system.rewrite_data_files( table => 'adb_iceberg_db.test_iceberg_tbl', strategy => 'sort', sort_order => 'id ASC NULLS FIRST', where => 'age = 10' );最佳化manifest檔案(rewrite_manifests)
CALL system.rewrite_manifests('adb_iceberg_db.test_iceberg_tbl');到期快照清理(expire_snapshots)
CALL system.expire_snapshots( table => 'adb_iceberg_db.test_iceberg_tbl', older_than => TIMESTAMP '2024-01-01 00:00:00', retain_last => 5 );快照復原(rollback_to_snapshot)
-- 先查詢快照列表擷取目標snapshot_id SELECT * FROM adb_iceberg_db.test_iceberg_tbl.snapshots; -- 復原到指定快照 CALL system.rollback_to_snapshot('adb_iceberg_db.test_iceberg_tbl', 1234567890);
除上述預存程序外,還支援remove_orphan_files(清理孤立檔案)和rollback_to_timestamp(按時間復原)等操作。完整列表請參見Apache Iceberg官方文檔。
AnalyticDB for MySQL增強預存程序
AnalyticDB for MySQL在標準Iceberg預存程序基礎上,額外提供了資料歸檔和生命週期管理能力。
資料歸檔(archive_files)
將冷資料歸檔到低成本儲存類型,降低儲存費用。
-- 歸檔30天前的資料到Archive儲存(dry_run=true表示僅預覽影響範圍,不實際執行) CALL system.archive_files( table => 'adb_iceberg_db.test_iceberg_tbl', storage_type => 'Archive', start_days => 30, dry_run => true );檢查歸檔狀態(check_archive_status)
查看各儲存類型下的檔案分布情況。
CALL system.check_archive_status( table => 'adb_iceberg_db.test_iceberg_tbl', group_by_partition => true );資料解凍(restore_files)
將已歸檔的資料恢複到標準儲存類型。
CALL system.restore_files( table => 'adb_iceberg_db.test_iceberg_tbl', where => 'age = 10' );分區生命週期管理(ttl)
基於分區的最後更新時間,識別或刪除到期分區。
-- 查看超過90天未更新的分區(dry_run=true表示僅預覽,不執行刪除) CALL system.ttl( table => 'adb_iceberg_db.test_iceberg_tbl', expire_after_days => 90, dry_run => true );
注意事項
不同Catalog模式的中繼資料一致性
三種Catalog模式各自獨立管理Iceberg表的中繼資料。在AnalyticDB for MySQL內部,MDS Catalog能夠感知通過Hadoop Catalog或湖儲存模式建立的表,因此在不添加額外配置的情況下也可以讀取這些表。但這不意味著可以跨模式混合寫入。
各Catalog模式之間的跨模式讀寫行為:
表的建立模式 | 通過MDS Catalog(預設) | 通過Hadoop Catalog | 通過湖儲存 |
MDS Catalog建立的表 | 讀寫正常 | 無法識別 | 無法識別 |
Hadoop Catalog建立的表 | 可讀取,不建議寫入 | 讀寫正常 | 不建議混用 |
湖儲存建立的表 | 可讀取,不建議寫入 | 可讀寫,但無法自動管理路徑 | 讀寫正常 |
請勿跨Catalog模式混合寫入同一張表。雖然MDS Catalog可以讀取Hadoop Catalog和湖儲存模式建立的表,但如果通過MDS Catalog寫入這些表,更新的中繼資料僅會記錄在MDS中,不會同步到Hadoop Catalog的檔案系統中繼資料。這將導致其他引擎讀取到的資料與實際資料不一致。
建議對同一張表,始終使用建立該表時所用的Catalog模式進行讀寫操作。如需跨產品協同,請在建表時選擇Hadoop Catalog或湖儲存模式。
運行環境配置
使用Iceberg相關功能時,Spark版本需為3.5及以上。如果叢集預設Spark版本不是3.5,請在SQL語句開頭添加
SET spark.adb.version=3.5;。根據所選的Catalog模式,需要配置不同模式的SET參數,不同資源群組的配置方式,請參見SET參數配置。
批處理與互動式模式
Spark SQL支援批處理和互動式兩種運行模式。請確認所使用的資源群組類型與運行模式相匹配。