Amazon S3 TablesでIcebergテーブルにソート順設定をしてみた
- Lipton

- 19 時間前
- 読了時間: 6分
はじめに
AWS上で大量データの分析を行いたいとき、RDBやDWHのサービス(例:RDS、Redshiftなど)を用いると非常にコストが高くなってしまうのが悩みの種でした。そこで、S3に配置したファイルをそのまま読み込んで分析を行うオープンテーブルフォーマットの需要が高まってきました。その中でも Apache Iceberg + Amazon S3 Tables(以下、S3 Tables)の組み合わせが昨今のトレンドとなっており、本記事ではS3 TablesのIcebergテーブルにソート順を追加するときに苦戦した点や注意するべき点などをご紹介しようと思います。
※本記事は2025年11月時点の情報に基づいて記載しています。AWSのアップデートなどにより、現在の仕様とは異なる可能性がありますので、その点はご了承ください。

S3 Tablesとは?
S3 Tables は、分析ワークロードに最適化された表形式データをS3上で直接管理できるサービスです。2024年12月のre:Invent 2024でプレビュー発表され、2025年初頭に一般提供(GA)が開始されました。東京リージョンでは2025年1月から利用可能になりました。
特徴としては以下が挙げられます。
通常のS3バケットと比べて、最大10倍のトランザクション性能
Apache Iceberg をネイティブにサポート
データ管理を「S3単体で完結」できる
これまでは「S3にファイルを置いて、Glue Data Catalogでテーブル定義を管理する」
という構成だったのが、「S3上のテーブルを直接管理・クエリできる」ようになったわけですね。
Apache Icebergとは?
Apache Iceberg は、データレイクのためのオープンテーブルフォーマットです。簡単に言うと、「巨大なS3上のParquetファイル群を、あたかもデータベースのテーブルのように扱う」ための仕組みです。
従来のHiveメタストアに比べて次のような利点があります。
スナップショットベースでのトランザクション管理
スキーマ変更(Schema Evolution)の柔軟な対応
パーティション管理の自動化(ファイル構造に依存しない)
データのバージョン管理やタイムトラベルクエリ
Apache IcebergとS3 Tablesについては以下のブログが詳しいので参考にどうぞ。
Athenaとの関係性
あるプロジェクトにて、以下のような構成で分析を行おうとしていました。
Redshift Spectrum → Icebergテーブル → Quicksight(現Quick Suite)
(クエリ実行はAthena)
この構成を用いるにあたっての課題が、Quick SuiteでIcebergテーブルをスキャンする際のコストでした。もちろんパーティションは切ってありましたが、パーティションしていない列を検索すると、どうしても全件スキャンが発生してしまうのが大きな課題でした。
これを改善するには、テーブルのソート順が大きな意味を持ちます。各ファイル内のデータが然るべきソート順で並び替えられていると、Athenaのスキャン範囲を狭めることができ、クエリ性能の向上とコスト削減が期待できます。
ただし、AthenaはINSERT時にカラムのソート順を無視して書き込むため、単純なINSERT文ではテーブルの並び順を保証できません。ORDER BY による並び替えはあくまで読み込んだデータの並び替えなので、書き込みの際には適用されません。
S3 Tablesを使うメリット
S3 Tablesでは、テーブル側にソート順(Sort Order)を設定できます。つまり、テーブル定義でソート条件を指定しておけば、書き込みを行う際にS3 Tablesが自動的に並び替えを反映してくれるようになったのです。
S3 Tablesの操作方法
以下のように操作できますが、ここでは具体的な操作方法については割愛します。
バケットの作成はコンソールから可能
テーブルの作成・削除はAthenaのクエリ、またはCLI経由で行う必要があります。コンソールからの実行はできません。
ソート順を設定するには
S3 Tablesでは、CREATE TABLE 時にソート順を直接設定できません。
代わりに以下のように ALTER TABLE を使います。
ALTER TABLE {テーブル名} WRITE ORDERED BY (カラム1, カラム2);ただし、Athenaではこの構文をサポートしていません。
Iceberg標準SQLをフルサポートしているのは以下の2サービスのみです。
Amazon EMR
AWS Glue
今回はAWS Glueで上記のクエリを実行するようにしてみました。
以下のユーザーガイドの「Amazon S3 Tables Catalog for Apache Iceberg」
を参考にしました。
ソート順を確認するには
テーブルに対してソート順の定義が反映されているかを確認するには、
以下のようにメタデータファイルを直接確認する必要があります。
メタデータファイルのパスはテーブルバケットコンソールから取得可能です。
aws s3 cp {メタデータファイルのパス} -出力されたメタデータの中に以下のような記述があればOKです。
order-idで定義されたソート順で書き込みが行われるようになります。
なお、テーブル定義を変更しただけでは既存のデータのソート順は変わらないため、再書き込みなどをする必要があります。
"default-sort-order-id" : 1,
"sort-orders" : [ {
"order-id" : 0,
"fields" : [ ]
}, {
"order-id" : 1,
"fields" : [ {
"transform" : "identity",
"source-id" : 3,
"direction" : "asc",
"null-order" : "nulls-first"
}, {
"transform" : "identity",
"source-id" : 10,
"direction" : "asc",
"null-order" : "nulls-first"
} ]
} ],AthenaでINSERTしてみると…
Icebergテーブルへのソート順の設定は完了したので、いよいよAthenaでINSERTの実行を行います。
しかし、以下のようなエラーが発生してしまいました。
GENERIC_INTERNAL_ERROR: Generic internal error. If a data manifest file was generated at '{S3バケット}/xxxxxx-manifest.csv', you may need to manually clean the data from locations specified in the manifest.これはAthena内部の整合性のエラーで、ソート順を設定する前のテーブルでは発生しませんでした。
Athenaは大規模データの書き込み時に複数のTaskで並列に処理し、最終的にcommit mergeで統合します。しかし、各Taskがソート順を無視して書き込むため、最終マージ時に整合性が取れず失敗してしまう、という仕組みのようです。
Athenaの内部の挙動についてはこちらを参考:https://trino.io/docs/current/overview/concepts.html#cluster
こちらのエラーについては、回避する方法が少量ずつのデータで実行するくらいしかなく、ソート順が設定されたテーブルへの大規模データのInsertにAthenaは不向きであると言えるでしょう。
AWSの公式ホワイトペーパー(Apache Iceberg on AWS, p.96)でも、ソート付きテーブルを扱う場合はEMRまたはGlueの利用を推奨しています。
なので、ソート付きテーブルに対するINSERTの実行は、
Athenaではなく EMRまたはGlue を使用するのが良いということになりますね。
SQLの実行はALTER TABLEを実行した時と同じ、以下の構成で実現できるためここでは割愛します。
まとめ
S3 Tablesは、AWSが目指す「S3中心のデータレイク管理」の中核を担う機能です。Icebergフォーマットをネイティブに扱えることで、S3上の大規模データを効率的に管理・アクセスでき、分析クエリのパフォーマンスを大幅に向上させることが可能になります。
とはいえ現時点では、Athena側に制約が多く、ソート順の反映や整合性の維持などの複雑な操作を行うにはEMR/Glueの利用が必要です。
ただ、まだ発表されてから1年足らずのサービスではあるので、今後のアップデートで劇的に変化する可能性が大いにあります。最新情報を見逃さないようにしたいですね。





コメント