

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Glue AWS 中使用 Iceberg 架構
<a name="aws-glue-programming-etl-format-iceberg"></a>

AWS Glue 3.0 和更新版本支援資料湖的 Apache Iceberg 架構。Iceberg 提供高效能的資料表格式，其運作方式就像 SQL 資料表一樣。本主題涵蓋在 Iceberg AWS 資料表中傳輸或存放資料時，在 Glue 中使用資料的可用功能。若要進一步了解 Iceberg，請參閱官方 [Apache Iceberg 文件](https://iceberg.apache.org/docs/latest/)。

您可以使用 AWS Glue 在 Amazon S3 中的 Iceberg 資料表上執行讀取和寫入操作，或使用 Glue Data Catalog 使用 Iceberg AWS 資料表。還支援包括插入和所有 [Spark 查詢](https://iceberg.apache.org/docs/latest/spark-queries/) [Spark 寫入](https://iceberg.apache.org/docs/latest/spark-writes/)在內的其他操作。Iceberg 資料表不支援更新。

**注意**  
`ALTER TABLE … RENAME TO` 不適用於 AWS Glue 3.0 的 Apache Iceberg 0.13.1。

下表列出每個 Glue 版本中包含的 Iceberg AWS 版本。


****  

| AWS Glue 版本 | 支援的 Iceberg 版本 | 
| --- | --- | 
| 5.1 | 1.10.0 | 
| 5.0 | 1.7.1 | 
| 4.0 | 1.0.0 | 
| 3.0 | 0.13.1 | 

若要進一步了解 AWS Glue 支援的資料湖架構，請參閱 [搭配 AWS Glue ETL 任務使用資料湖架構](aws-glue-programming-etl-datalake-native-frameworks.md)。

## 啟用 Iceberg 架構
<a name="aws-glue-programming-etl-format-iceberg-enable"></a>

若要啟用 Iceberg for AWS Glue，請完成下列任務：
+ 指定 `iceberg` 作為 `--datalake-formats` 任務參數的值。如需詳細資訊，請參閱[在 Glue AWS 任務中使用任務參數](aws-glue-programming-etl-glue-arguments.md)。
+ 為您的 Glue 任務建立名為 AWS `--conf`的金鑰，並將其設定為下列值。您也可以選擇在指令碼中使用 `SparkConf` 設定以下組態。這些設定有助於 Apache Spark 正確處理 Iceberg 資料表。

  ```
  spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions 
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog 
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://<your-warehouse-dir>/ 
  --conf spark.sql.catalog.glue_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
  --conf spark.sql.catalog.glue_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO
  ```

  如果您要讀取或寫入已向 Lake Formation 註冊的 Iceberg 資料表，請遵循 AWS Glue 5.0 和更新[搭配 AWS 使用 Glue AWS Lake Formation 進行精細存取控制](security-lf-enable.md)版本中的指引。在 AWS Glue 4.0 中，新增下列組態以啟用 Lake Formation 支援。

  ```
  --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true
  --conf spark.sql.catalog.glue_catalog.glue.id=<table-catalog-id>
  ```

  如果您將 AWS Glue 3.0 與 Iceberg 0.13.1 搭配使用，則必須將下列其他組態設定為使用 Amazon DynamoDB 鎖定管理員以確保原子交易。 AWS Glue 4.0 或更新版本預設使用樂觀鎖定。如需詳細資訊，請參閱官方 Apache [Iceberg 文件中的 Iceberg AWS 整合](https://iceberg.apache.org/docs/latest/aws/#dynamodb-lock-manager)。

  ```
  --conf spark.sql.catalog.glue_catalog.lock-impl=org.apache.iceberg.aws.glue.DynamoLockManager 
  --conf spark.sql.catalog.glue_catalog.lock.table=<your-dynamodb-table-name>
  ```

**使用不同的 Iceberg 版本**

若要使用 AWS Glue 不支援的 Iceberg 版本，請使用 `--extra-jars`任務參數指定您自己的 Iceberg JAR 檔案。請勿包括 `iceberg` 作為 `--datalake-formats` 參數的值。如果您使用 AWS Glue 5.0 或更新版本，則必須設定`--user-jars-first true`任務參數。

**啟用 Iceberg 資料表的加密**

**注意**  
Iceberg 資料表具有自己的機制來啟用伺服器端加密。除了 Glue AWS 的安全組態之外，您應該啟用此組態。

若要在 Iceberg 資料表上啟用伺服器端加密，請檢閱 [Iceberg 文件](https://iceberg.apache.org/docs/latest/aws/#s3-server-side-encryption)中的指引。

**新增 Iceberg 跨區域的 Spark 組態**

若要使用 Glue Data Catalog 為 Iceberg 跨區域資料表存取新增額外的 Spark AWS 組態 AWS Lake Formation，請遵循下列步驟：

1. 建立[多區域存取點](https://docs.aws.amazon.com/AmazonS3/latest/userguide/multi-region-access-point-create-examples.html)。

1. 設定下列 Spark 屬性：

   ```
   -----
       --conf spark.sql.catalog.my_catalog.s3.use-arn-region-enabled=true \
       --conf spark.sql.catalog.{CATALOG}.s3.access-points.bucket1", "arn:aws:s3::<account-id>:accesspoint/<mrap-id>.mrap \
       --conf spark.sql.catalog.{CATALOG}.s3.access-points.bucket2", "arn:aws:s3::<account-id>:accesspoint/<mrap-id>.mrap
   -----
   ```

## 範例：將 Iceberg 資料表寫入 Amazon S3，並將其註冊到 AWS Glue Data Catalog
<a name="aws-glue-programming-etl-format-iceberg-write"></a>

此範例指令碼示範如何將 Iceberg 資料表寫入 Amazon S3。此範例使用 [Iceberg AWS 整合](https://iceberg.apache.org/docs/latest/aws/)將資料表註冊至 AWS Glue Data Catalog。

------
#### [ Python ]

```
# Example: Create an Iceberg table from a DataFrame 
# and register the table to Glue Data Catalog

dataFrame.createOrReplaceTempView("tmp_<your_table_name>")

query = f"""
CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
USING iceberg
TBLPROPERTIES ("format-version"="2")
AS SELECT * FROM tmp_<your_table_name>
"""
spark.sql(query)
```

------
#### [ Scala ]

```
// Example: Example: Create an Iceberg table from a DataFrame
// and register the table to Glue Data Catalog

dataFrame.createOrReplaceTempView("tmp_<your_table_name>")

val query = """CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
USING iceberg
TBLPROPERTIES ("format-version"="2")
AS SELECT * FROM tmp_<your_table_name>
"""
spark.sql(query)
```

------

或者，您可使用 Spark 方法將 Iceberg 資料表寫入 Amazon S3 和 Data Catalog。

先決條件：您需要佈建目錄才能使用 Iceberg 程式庫。使用 AWS Glue Data Catalog 時， AWS Glue 會直接執行此操作。Glue Data Catalog AWS 已預先設定為供 Spark 程式庫使用，做為 `glue_catalog`。資料目錄資料表由 *databaseName* 和 *tableName* 識別。如需 AWS Glue Data Catalog 的詳細資訊，請參閱 [中的資料探索和目錄編製 AWS Glue](catalog-and-crawler.md)。

如果您不是使用 AWS Glue Data Catalog，則需要透過 Spark APIs佈建目錄。如需詳細資訊，請參閱 Iceberg 文件中的 [Spark 組態](https://iceberg.apache.org/docs/latest/spark-configuration/)。

此範例使用 Spark 將 Iceberg 資料表寫入至 Amazon S3 和 Data Catalog。

------
#### [ Python ]

```
# Example: Write an Iceberg table to S3 on the Glue Data Catalog

# Create (equivalent to CREATE TABLE AS SELECT)
dataFrame.writeTo("glue_catalog.databaseName.tableName") \
    .tableProperty("format-version", "2") \
    .create()

# Append (equivalent to INSERT INTO)
dataFrame.writeTo("glue_catalog.databaseName.tableName") \
    .tableProperty("format-version", "2") \
    .append()
```

------
#### [ Scala ]

```
// Example: Write an Iceberg table to S3 on the Glue Data Catalog

// Create (equivalent to CREATE TABLE AS SELECT)
dataFrame.writeTo("glue_catalog.databaseName.tableName")
    .tableProperty("format-version", "2")
    .create()

// Append (equivalent to INSERT INTO)
dataFrame.writeTo("glue_catalog.databaseName.tableName")
    .tableProperty("format-version", "2")
    .append()
```

------

## 範例：使用 Glue Data Catalog 從 Amazon S3 AWS 讀取 Iceberg 資料表
<a name="aws-glue-programming-etl-format-iceberg-read"></a>

此範例會讀取您在 [範例：將 Iceberg 資料表寫入 Amazon S3，並將其註冊到 AWS Glue Data Catalog](#aws-glue-programming-etl-format-iceberg-write) 中建立的 Iceberg 資料表。

------
#### [ Python ]

在此範例中，使用 `GlueContext.create\$1data\$1frame.from\$1catalog()` 方法。

```
# Example: Read an Iceberg table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

df = glueContext.create_data_frame.from_catalog(
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

------
#### [ Scala ]

在此範例中，使用 [getCatalogSource](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSource) 方法。

```
// Example: Read an Iceberg table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    val df = glueContext.getCatalogSource("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .getDataFrame()
  }
}
```

------

## 範例：使用 Glue Data Catalog 將 `DataFrame`插入 Amazon S3 中的 Iceberg AWS 資料表
<a name="aws-glue-programming-etl-format-iceberg-insert"></a>

此範例會將資料插入您在 [範例：將 Iceberg 資料表寫入 Amazon S3，並將其註冊到 AWS Glue Data Catalog](#aws-glue-programming-etl-format-iceberg-write) 中建立的 Iceberg 資料表中。

**注意**  
此範例需要您設定`--enable-glue-datacatalog`任務參數，才能使用 AWS Glue Data Catalog 做為 Apache Spark Hive 中繼存放區。如需詳細資訊，請參閱 [在 Glue AWS 任務中使用任務參數](aws-glue-programming-etl-glue-arguments.md)。

------
#### [ Python ]

在此範例中，使用 `GlueContext.write\$1data\$1frame.from\$1catalog()` 方法。

```
# Example: Insert into an Iceberg table from Glue Data Catalog

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)

glueContext.write_data_frame.from_catalog(
    frame=dataFrame,
    database="<your_database_name>",
    table_name="<your_table_name>",
    additional_options=additional_options
)
```

------
#### [ Scala ]

在此範例中，使用 [getCatalogSink](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getCatalogSink) 方法。

```
// Example: Insert into an Iceberg table from Glue Data Catalog

import com.amazonaws.services.glue.GlueContext
import org.apacke.spark.SparkContext

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    glueContext.getCatalogSink("<your_database_name>", "<your_table_name>",
      additionalOptions = additionalOptions)
      .writeDataFrame(dataFrame, glueContext)
  }
}
```

------

## 範例：使用 Spark 從 Amazon S3 讀取 Iceberg 資料表
<a name="aws-glue-programming-etl-format-iceberg-read-spark"></a>

先決條件：您需要佈建目錄才能使用 Iceberg 程式庫。使用 AWS Glue Data Catalog 時， AWS Glue 會直接執行此操作。Glue Data Catalog AWS 已預先設定為供 Spark 程式庫使用，做為 `glue_catalog`。資料目錄資料表由 *databaseName* 和 *tableName* 識別。如需 AWS Glue Data Catalog 的詳細資訊，請參閱 [中的資料探索和目錄編製 AWS Glue](catalog-and-crawler.md)。

如果您不是使用 AWS Glue Data Catalog，則需要透過 Spark APIs佈建目錄。如需詳細資訊，請參閱 Iceberg 文件中的 [Spark 組態](https://iceberg.apache.org/docs/latest/spark-configuration/)。

此範例使用 Spark 從資料目錄讀取 Amazon S3 中的 Iceberg 資料表。

------
#### [ Python ]

```
# Example: Read an Iceberg table on S3 as a DataFrame from the Glue Data Catalog

dataFrame = spark.read.format("iceberg").load("glue_catalog.databaseName.tableName")
```

------
#### [ Scala ]

```
// Example: Read an Iceberg table on S3 as a DataFrame from the Glue Data Catalog

val dataFrame = spark.read.format("iceberg").load("glue_catalog.databaseName.tableName")
```

------

## 範例：使用 Lake Formation 權限控制讀取和寫入 Iceberg 資料表
<a name="aws-glue-programming-etl-format-iceberg-read-write-lake-formation-tables"></a>

此範例會使用 Lake Formation 權限控制讀取和寫入 Iceberg 資料表。

**注意**  
此範例僅適用於 AWS Glue 4.0。在 AWS Glue 5.0 和更新版本中，請遵循 中的指引。 [搭配 AWS 使用 Glue AWS Lake Formation 進行精細存取控制](security-lf-enable.md)

1. 建立 Iceberg 資料表，並在 Lake Formation 進行註冊：

   1. 若要啟用 Lake Formation 權限控制，您將需要先在 Lake Formation 中註冊資料表 Amazon S3 路徑。如需詳細資訊，請參閱 [Registering an Amazon S3 location](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html) (註冊 Amazon S3 位置)。您可以從 Lake Formation 主控台或使用 CLI AWS 註冊：

      ```
      aws lakeformation register-resource --resource-arn arn:aws:s3:::<s3-bucket>/<s3-folder> --use-service-linked-role --region <REGION>
      ```

      註冊 Amazon S3 位置後，指向位置 （或其任何子位置） 的任何 AWS Glue 資料表都會在`GetTable`呼叫中傳回 `IsRegisteredWithLakeFormation` 參數的值為 true。

   1. 建立透過 Spark SQL 指向註冊之路徑的 Iceberg 資料表：
**注意**  
下列為 Python 範例。

      ```
      dataFrame.createOrReplaceTempView("tmp_<your_table_name>")
      
      query = f"""
      CREATE TABLE glue_catalog.<your_database_name>.<your_table_name>
      USING iceberg
      AS SELECT * FROM tmp_<your_table_name>
      """
      spark.sql(query)
      ```

      您也可以透過 Glue `CreateTable` API AWS 手動建立資料表。如需詳細資訊，請參閱[建立 Apache Iceberg 資料表](https://docs.aws.amazon.com/lake-formation/latest/dg/creating-iceberg-tables.html)。
**注意**  
`UpdateTable` API 目前不支援 Iceberg 資料表格式作為操作的輸入。

1. 將 Lake Formation 權限授予任務 IAM 角色。您可以從 Lake Formation 主控台授予許可，或使用 AWS CLI。如需詳細資訊，請參閱：https://docs.aws.amazon.com/lake-formation/latest/dg/granting-table-permissions.html

1. 讀取向 Lake Formation 註冊的 Iceberg 資料表。該程式碼與讀取未註冊之 Iceberg 資料表的程式碼相同。請注意，您的 AWS Glue 任務 IAM 角色需要具有 SELECT 許可，才能成功讀取。

   ```
   # Example: Read an Iceberg table from the AWS Glue Data Catalog
   from awsglue.context import GlueContextfrom pyspark.context import SparkContext
   
   sc = SparkContext()
   glueContext = GlueContext(sc)
   
   df = glueContext.create_data_frame.from_catalog(
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```

1. 寫入向 Lake Formation 註冊的 Iceberg 資料表。該程式碼與寫入未註冊之 Iceberg 資料表的程式碼相同。請注意，您的 AWS Glue 任務 IAM 角色需要具有 SUPER 許可才能成功寫入。

   ```
   glueContext.write_data_frame.from_catalog(
       frame=dataFrame,
       database="<your_database_name>",
       table_name="<your_table_name>",
       additional_options=additional_options
   )
   ```