Skip to content

Amazon S3 Tables + Amazon Athena / Apache Iceberg 参加レポート

2025年4月12日に開催された、流しのエバンジェリスト 亀田さんによるオンラインハンズオン「Amazon S3 Tables + Amazon Athena / Apache Iceberg」に参加した際のレポートです。

イベント情報

connpass ページ:Amazon S3 Tables + Amazon Athena / Apache Iceberg

AWS SA 下佐粉さんによる Apache Iceberg そして Amazon S3 Tables の説明

Apache Iceberg について

データレイクの基本として処理と蓄積を分離して疎結合にすることが大切。 処理は時代によって変わるので、処理系をいつでも捨てられるようにすることが重要。

20250412_awsbasics-01 20250412_awsbasics-02

Apache Iceberg はデータレイヤーとエンジンの間に位置する OTF(Open Table Format)のひとつであってテーブルフォーマット(フォーマット規格)。 独立したソフトウェアではない

20250412_awsbasics-03 20250412_awsbasics-04 20250412_awsbasics-05

クエリエンジンから見たときに、従来はカタログ実装ごとに仕様を知っている必要があった。 これが Iceberg REST API として実装・標準化されたことで、OPEN API の仕様さえ知っていれば、個別のカタログ専用の実装が不要になる

20250412_awsbasics-06 20250412_awsbasics-07 20250412_awsbasics-08

Amazon S3 Tables について

従来の S3 バケットは異なり「S3 テーブルバケット」を作成して利用するクラウドオブジェクトストア

20250412_awsbasics-12

S3 テーブルバケットの構成要素とメンテナンスの重要性

Iceberg では変更が起こった際、該当行に変更履歴や内容を付記するようなメタデータを持たせデータ行の書き換えをせずに処理して迅速化を測っている 大量の更新があった場合、メタデータの大量発生につながるためメンテナンスタスクが必要になるが、S3 Tables では裏側でやってくれる

20250412_awsbasics-13

下佐粉さんによるまとめ

20250412_awsbasics-14 20250412_awsbasics-15

亀田さんによるハンズオン

ハンズオン資料

Amazon S3 Tables (Apache Iceberg) をやってみる

ハンズオンの前提としての注意事項

テーブルバケットの AWS 分析サービスとの統合の際に Glue や Lake Formation 関連の操作を行うが、root アカウントに対して Lake Formation の権限付与ができないので、AdministratorAccess など書き込み系の権限のある IAM エンティティで操作する必要がある

テーブルバケットの作成

1
2
3
aws s3tables create-table-bucket \
  --name 20250412-awsbasics-ichino \
  --region us-east-1

上記を実行すると、以下のように ARN が返却される。

1
2
3
{
    "arn": "arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino"
}

namespace の作成

テーブルバケットの作成時の ARN を控えておき、AWS CLI の s3tables create-namespace サブコマンドで作成。

1
2
3
aws s3tables create-namespace \
  --table-bucket-arn arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino \
  --namespace 202504ichino

当初、namespace を 202504-ichino として実行していたが An error occurred (BadRequestException) when calling the CreateNamespace operation: The specified namespace name is not valid. のエラーが発生。 後述の通り namespace の命名規則が厳しく aws s3tables create-namespace help を実行しても特に何の情報も得られなかったため API リファレンスで確認。

ハマりどころ1:S3 Tables の namespace の命名規則

以下にあるように最大 255 文字までの [0-9a-z_]* のパターンである必要がある。

CreateNamespace - Amazon Simple Storage Service

A name for the namespace.
Type: Array of strings
Array Members: Fixed number of 1 item.
Length Constraints: Minimum length of 1. Maximum length of 255.
Pattern: [0-9a-z_]*
Required: Yes

テーブルの作成

テーブルバケットの ARN と、ひとつ前の手順で作成した namespace を指定し、table.json を作成。
作成した table.json を使用し s3tables create-table でテーブルを作成。

テーブルの作成用 JSON ファイルの作成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
cat << EOF > table.json
{
    "tableBucketARN": "arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino",
    "namespace": "202504ichino",
    "name": "my_table",
    "format": "ICEBERG",
    "metadata": {
        "iceberg": {
            "schema": {
                "fields": [
                     {"name": "id", "type": "int","required": true},
                     {"name": "name", "type": "string"},
                     {"name": "value", "type": "int"}
                ]
            }
        }
    }
}
EOF

テーブルの作成

1
aws s3tables create-table --cli-input-json file://table.json

Athena を利用したクエリの実行

データの投入

4月12日 15:12 頃に実行

1
2
3
4
INSERT INTO "202504ichino".my_table
VALUES 
    (111, 'ABC', 100),
    (222, 'XYZ', 200);

4月12日 15:27 頃に実行

1
2
3
4
INSERT INTO "202504ichino".my_table
VALUES 
    (333, 'DEF', 300),
    (444, 'abc', 400);

データの取得

1
SELECT * FROM "202504ichino".my_table;

20250412_awsbasics-09

タイムトラベルクエリの実行

まずは、2回目の INSERT を行った後くらいの時間帯を指定して実施

SELECT * 〜 で全件取得した時と同様の内容が取得できている。

1
2
select * from "202504ichino"."my_table" 
FOR TIMESTAMP AS OF TIMESTAMP '2025-04-12 6:28:00 UTC';

20250412_awsbasics-10

次に 2回目の INSERT を行う1分前くらい指定して実施

id が 111222 のデータのみ返却されていることが確認できた。

1
2
select * from "202504ichino"."my_table" 
FOR TIMESTAMP AS OF TIMESTAMP '2025-04-12 6:26:00 UTC';

20250412_awsbasics-11

ハマりどころ2:Athena クエリ実行時の SQL 文

SQL を長らく書いていなかったので、当初以下のような SQL としていて Queries of this type are not supported というエラーが発生。
識別子を数字から始められず回避するにはダブルクォートで囲む必要があり、この部分でもハマってしまった。

1
2
3
4
INSERT INTO 202504ichino.my_table
VALUES 
    (111, 'ABC', 100),
    (222, 'XYZ', 200);

おかたづけ

現時点(2025-04-12)で、テーブル、テーブルバケットの削除はマネジメントコンソールでは実施できず、AWS CLI や AWS SDK、Amazon S3 REST API で実施する必要があるとのこと。

テーブルの削除

1
2
3
4
aws s3tables delete-table \
  --table-bucket-arn arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino \
  --namespace 202504ichino \
  --name my_table

namespace の削除

1
2
3
aws s3tables delete-namespace \
  --table-bucket-arn arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino \
  --namespace 202504ichino

テーブルバケットの削除

1
2
3
aws s3tables delete-table-bucket \
  --table-bucket-arn arn:aws:s3tables:us-east-1:123456789012:bucket/20250412-awsbasics-ichino \
  --region us-east-1

ハマりどころ3:Amazon S3 Tables の削除

ハマりどころ1 のところで AWS CLI の help を参照しようと思って、help という namespace も作成してしまっていた模様。

そのため前述の「おかたづけ」手順通りやっても s3tables delete-table-bucket サブコマンド実行時に An error occurred (BadRequestException) when calling the DeleteTableBucket operation: The bucket that you tried to delete is not empty. というエラーが発生してテーブルバケットの削除ができなかった。

テーブル自体は s3tables list-tables サブコマンドやマネジメントコンソールで確認できるが、namespace がマネジメントコンソールで確認できず s3tables list-namespaces サブコマンドで探し当てて削除した。

亀田さんの手順書の通り、「テーブルの削除」→「namespace の削除」を全て済ませてから「テーブルバケットの削除」を実行する順序性がある模様。


何はともあれハンズオン手順は全て完走。

Comments