

# AWS Glue での Iceberg フレームワークの使用
<a name="aws-glue-programming-etl-format-iceberg"></a>

AWS Glue 3.0 以降では、データレイク向けに Apache Iceberg フレームワークがサポートされています。Iceberg により、SQL テーブルと同様な機能を持つ、高性能なテーブルフォーマットが提供されます。このトピックでは、AWS Glue 内でデータを Iceberg テーブルに転送または保存する際に利用可能な、機能について説明します。Iceberg の詳細については、公式の[Apache Iceberg ドキュメント](https://iceberg.apache.org/docs/latest/)を参照してください。

Amazon S3 内の Iceberg テーブルに対する読み取りと書き込みの操作は、AWS Glue を使用して実行することができます。あるいは、AWS Glue データカタログを使用して Iceberg テーブルを操作することも可能です。挿入に加え、「[Spark クエリ](https://iceberg.apache.org/docs/latest/spark-queries/)」 や 「[Spark 書き込み](https://iceberg.apache.org/docs/latest/spark-writes/)」 のすべての操作も、追加でサポートされています。更新は Iceberg テーブルではサポートされていません。

**注記**  
Apache Iceberg 0.13.1 for AWS Glue 3.0 では、`ALTER TABLE … RENAME TO` はサポートされません。

次の表に、AWS Glue の各バージョンに含まれる Iceberg のバージョンを一覧で示します。


****  

| 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>

AWS Glue で Iceberg を有効化するには、以下のタスクを実行します。
+ `iceberg` を `--datalake-formats` のジョブパラメータの値として指定します。詳細については、「[AWS Glue ジョブでジョブパラメータを使用する](aws-glue-programming-etl-glue-arguments.md)」を参照してください。
+ AWS Glue ジョブ用に、`--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 ロックマネージャーを使用して確実なアトミックトランザクションを行うために、次の追加事項を設定する必要があります。 AWSGlue 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 ファイルを指定します。`--datalake-formats` パラメータの値として、`iceberg` を含めないようにしてください。AWS Glue 5.0 以降を使用する場合、`--user-jars-first true` ジョブパラメータを設定する必要があります。

**Iceberg テーブルの暗号化を有効にする**

**注記**  
Iceberg テーブルにはサーバー側の暗号化を有効にする独自のメカニズムがあります。AWS Glue のセキュリティ設定に加えて、これらの設定を有効にする必要があります。

Iceberg テーブルでサーバー側の暗号化を有効にするには、「[Iceberg ドキュメント](https://iceberg.apache.org/docs/latest/aws/#s3-server-side-encryption)」のガイダンスを確認してください。

**Iceberg クロスリージョンに Spark 設定を追加する**

AWS Glue Data Catalog および AWS Lake Formation を使用して Iceberg クロスリージョンテーブルアクセスの Spark 設定を追加するには、以下の手順に従います。

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
   -----
   ```

## 例: Amazon S3 に Iceberg テーブルを書き込み、そのテーブルを AWS Glue データカタログに登録する
<a name="aws-glue-programming-etl-format-iceberg-write"></a>

このスクリプト例は、Amazon S3 に Iceberg テーブルを書き込む方法を示しています。この例では、[Iceberg と AWS の統合](https://iceberg.apache.org/docs/latest/aws/)を使用して、テーブルを AWS Glue データカタログに登録しています。

------
#### [ 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 メソッドを使用して Amazon S3 とデータカタログに Iceberg テーブルを書き込むこともできます。

前提条件: Iceberg ライブラリが使用するカタログを用意する必要があります。AWS Glue データカタログを使う場合、AWS Glue を使えば簡単です。AWS Glue データカタログは、`glue_catalog` として Spark ライブラリで使用できるように事前に設定されています。データカタログテーブルは、*atabaseName* と*tableName* で識別されます。AWS Glue データカタログの詳細については、「[AWS Glue でのデータ検出とカタログ化](catalog-and-crawler.md)」を参照してください

AWS Glue データカタログを使用していない場合は、Spark API を使用してカタログをプロビジョニングする必要があります。詳細については、Spark ドキュメントの「[Spark の設定](https://iceberg.apache.org/docs/latest/spark-configuration/)」を参照してください。

この例では、Spark を使用して Amazon S3 と データカタログに Iceberg テーブルを書き込みます。

------
#### [ 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()
```

------

## 例: AWS Glue データカタログを使用した Amazon S3 からの Iceberg テーブルの読み込み
<a name="aws-glue-programming-etl-format-iceberg-read"></a>

この例では、「[例: Amazon S3 に Iceberg テーブルを書き込み、そのテーブルを AWS Glue データカタログに登録する](#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()
  }
}
```

------

## 例: AWS Glue データカタログを使用した Amazon S3 にある Iceberg テーブルへの `DataFrame` の挿入
<a name="aws-glue-programming-etl-format-iceberg-insert"></a>

この例では、「[例: Amazon S3 に Iceberg テーブルを書き込み、そのテーブルを AWS Glue データカタログに登録する](#aws-glue-programming-etl-format-iceberg-write)」で作成した Iceberg テーブルにデータを挿入します。

**注記**  
この例では、AWS Glue データカタログを Apache Spark Hive のメタストアとして使用するために、`--enable-glue-datacatalog` ジョブパラメータの設定が必要となります。詳細については[AWS Glue ジョブでジョブパラメータを使用する](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 を使用した Iceberg テーブルの Amazon S3 からの読み取り
<a name="aws-glue-programming-etl-format-iceberg-read-spark"></a>

前提条件: Iceberg ライブラリが使用するカタログを用意する必要があります。AWS Glue データカタログを使う場合、AWS Glue を使えば簡単です。AWS Glue データカタログは、`glue_catalog` として Spark ライブラリで使用できるように事前に設定されています。データカタログテーブルは、*atabaseName* と*tableName* で識別されます。AWS Glue データカタログの詳細については、「[AWS Glue でのデータ検出とカタログ化](catalog-and-crawler.md)」を参照してください

AWS Glue データカタログを使用していない場合は、Spark API を使用してカタログをプロビジョニングする必要があります。詳細については、Spark ドキュメントの「[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 の許可のコントロールを有効にするには、まずテーブルの Amazon S3 パスを Lake Formation に登録する必要があります。詳細については、「[Registering an Amazon S3 location](https://docs.aws.amazon.com/lake-formation/latest/dg/register-location.html)」を参照してください。Lake Formation コンソールから、または AWS CLI を使用して登録できます。

      ```
      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)
      ```

      AWS Glue `CreateTable` API を通じてテーブルを手動で作成することもできます。詳細については、「[Apache Iceberg テーブルの作成](https://docs.aws.amazon.com/lake-formation/latest/dg/creating-iceberg-tables.html)」を参照してください。
**注記**  
`UpdateTable` API は現在、 オペレーションへの入力として Iceberg テーブル形式をサポートしていません。

1. ジョブ IAM ロールに Lake Formation の許可を付与します。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
   )
   ```