Amazon Web Services ブログ

新機能: sort コンパクションと z-order コンパクションで Amazon S3 内での Apache Iceberg クエリパフォーマンスを向上

sort コンパクションと z-order コンパクションを使用して、Amazon S3 Tables汎用 S3 バケットでの Apache Iceberg クエリパフォーマンスを向上させることが可能になりました。

通常、Iceberg は AWS Glue データカタログや S3 Tables で Amazon Simple Storage Service (Amazon S3) 内の大規模な分析データセットを管理するために使用します。Iceberg テーブルは、同時ストリーミングやバッチインジェスト、スキーマ進化、タイムトラベルなどのユースケースをサポートします。高インジェストまたは頻繁に更新されるデータセットを扱うときは、データレイクに多数の小さなファイルが蓄積される場合があり、クエリのコストやパフォーマンスに影響を及ぼします。皆さんからは、Iceberg のデータレイアウトの最適化は操作が複雑で、多くの場合にカスタムパイプラインの開発と維持が必要になるというご意見をいただいています。マネージドコンパクションでのデフォルトの binpack 戦略はパフォーマンスを大幅に向上させますが、S3 と S3 Tables の両方に sort および z-order のコンパクションオプションを導入すると、1 つ、または複数のディメンション全体をフィルタリングするクエリのパフォーマンスがさらに大きく向上します。

2 つの新しいコンパクション戦略: Sortz-order
データをより効率的に整理するため、Amazon S3 では、デフォルトの binpack コンパクションに加えて、sortz-order の 2 つの新しいコンパクション戦略がサポートされるようになりました。これらの高度な戦略は、AWS Glue データカタログによる最適化を通じて、フルマネージド型の S3 Tables と、汎用 S3 バケット内の Iceberg テーブルの両方で利用できます。

Sort コンパクションは、ユーザー定義の列順序に基づいてファイルを整理します。テーブルにソート順序が定義されている場合、S3 Tables コンパクションはコンパクションプロセス時にそのソート順序を使用して、類似する値をクラスター化するようになります。これは、スキャンされるファイルの数を減らすことでクエリの実行効率性を向上させます。例えば、statezip_code による sort コンパクションでテーブルが整理されている場合、これらの列をフィルタリングするクエリでスキャンされるファイル数が減るため、レイテンシーとクエリエンジンコストが低減します。

Z-order コンパクションは、複数のディメンション全体で効率的なファイルプルーニングを有効にすることで、ファイルをさらに整理します。この戦略は、複数の列からの値の二進数表現をソート可能な単一のスカラーにインターリーブするため、空間クエリや多次元クエリには特に有用です。例えば、ワークロードに pickup_locationdropoff_location、および fare_amount で同時にフィルタリングするクエリが含まれる場合に z-order コンパクションを使用すると、スキャンされるファイルの総数を従来のソートベースのレイアウトよりも少なくすることができます。

S3 Tables は、Iceberg テーブルのメタデータを使用して現行のソート順序を判断します。テーブルにソート順序が定義されている場合は、継続的なメンテナンス時に sort コンパクションが自動的に適用されるため、アクティブ化するための追加設定は必要ありません。z-order を使用するには、S3 Tables API を使用してテーブルのメンテナンス設定を更新し、戦略を z-order に設定する必要があります。汎用 S3 バケット内の Iceberg テーブルの場合は、コンパクション設定を更新することで、最適化の最中に sort または z-order コンパクションを使用するように AWS Glue データカタログを設定できます。

sort または z-order の対象となるのは、これらを有効化した後で書き込まれた新しいデータのみです。コンパクション実施済みの既存ファイルは、テーブルのメンテナンス設定でターゲットファイルのサイズを大きくするか、標準の Iceberg ツールを使用してデータを書き換えることでファイルを明示的に書き換える場合を除き、そのまま変更されません。この動作は、いつ、どのくらいのデータを整理し直すかをユーザーが制御して、コストとパフォーマンスのバランスを取ることができるように設計されたものです。

実際の動作を見てみましょう
ここでは、Apache Spark と AWS コマンドラインインターフェイス (AWS CLI) を使用するシンプルな例を説明していきます。インストール済みの Spark クラスターと S3 テーブルバケットを用意しました。testnamespace 内には testtable という名前のテーブルがあります。テーブルにデータを追加できるように、コンパクションを一時的に無効にしました。

データを追加したら、テーブルのファイル構造を確認します。

spark.sql("""
  SELECT 
    substring_index(file_path, '/', -1) as file_name,
    record_count,
    file_size_in_bytes,
    CAST(UNHEX(hex(lower_bounds[2])) AS STRING) as lower_bound_name,
    CAST(UNHEX(hex(upper_bounds[2])) AS STRING) as upper_bound_name
  FROM ice_catalog.testnamespace.testtable.files
  ORDER BY file_name
""").show(20, false)
+--------------------------------------------------------------+------------+------------------+----------------+----------------+
|file_name                                                     |record_count|file_size_in_bytes|lower_bound_name|upper_bound_name|
+--------------------------------------------------------------+------------+------------------+----------------+----------------+
|00000-0-66a9c843-5a5c-407f-8da4-4da91c7f6ae2-0-00001.parquet  |1           |837               |Quinn           |Quinn           |
|00000-1-b7fa2021-7f75-4aaf-9a24-9bdbb5dc08c9-0-00001.parquet  |1           |824               |Tom             |Tom             |
|00000-10-00a96923-a8f4-41ba-a683-576490518561-0-00001.parquet |1           |838               |Ilene           |Ilene           |
|00000-104-2db9509d-245c-44d6-9055-8e97d4e44b01-0-00001.parquet|1000000     |4031668           |Anjali          |Tom             |
|00000-11-27f76097-28b2-42bc-b746-4359df83d8a1-0-00001.parquet |1           |838               |Henry           |Henry           |
|00000-114-6ff661ca-ba93-4238-8eab-7c5259c9ca08-0-00001.parquet|1000000     |4031788           |Anjali          |Tom             |
|00000-12-fd6798c0-9b5b-424f-af70-11775bf2a452-0-00001.parquet |1           |852               |Georgie         |Georgie         |
|00000-124-76090ac6-ae6b-4f4e-9284-b8a09f849360-0-00001.parquet|1000000     |4031740           |Anjali          |Tom             |
|00000-13-cb0dd5d0-4e28-47f5-9cc3-b8d2a71f5292-0-00001.parquet |1           |845               |Olivia          |Olivia          |
|00000-134-bf6ea649-7a0b-4833-8448-60faa5ebfdcd-0-00001.parquet|1000000     |4031718           |Anjali          |Tom             |
|00000-14-c7a02039-fc93-42e3-87b4-2dd5676d5b09-0-00001.parquet |1           |838               |Sarah           |Sarah           |
|00000-144-9b6d00c0-d4cf-4835-8286-ebfe2401e47a-0-00001.parquet|1000000     |4031663           |Anjali          |Tom             |
|00000-15-8138298d-923b-44f7-9bd6-90d9c0e9e4ed-0-00001.parquet |1           |831               |Brad            |Brad            |
|00000-155-9dea2d4f-fc98-418d-a504-6226eb0a5135-0-00001.parquet|1000000     |4031676           |Anjali          |Tom             |
|00000-16-ed37cf2d-4306-4036-98de-727c1fe4e0f9-0-00001.parquet |1           |830               |Brad            |Brad            |
|00000-166-b67929dc-f9c1-4579-b955-0d6ef6c604b2-0-00001.parquet|1000000     |4031729           |Anjali          |Tom             |
|00000-17-1011820e-ee25-4f7a-bd73-2843fb1c3150-0-00001.parquet |1           |830               |Noah            |Noah            |
|00000-177-14a9db71-56bb-4325-93b6-737136f5118d-0-00001.parquet|1000000     |4031778           |Anjali          |Tom             |
|00000-18-89cbb849-876a-441a-9ab0-8535b05cd222-0-00001.parquet |1           |838               |David           |David           |
|00000-188-6dc3dcca-ddc0-405e-aa0f-7de8637f993b-0-00001.parquet|1000000     |4031727           |Anjali          |Tom             |
+--------------------------------------------------------------+------------+------------------+----------------+----------------+
only showing top 20 rows

テーブルが複数の小さなファイルで構成されており、新しいファイルの上限値と下限値が重複していることがわかります。データは明らかにソートされていません。

テーブルのソート順序を設定します。

spark.sql("ALTER TABLE ice_catalog.testnamespace.testtable WRITE ORDERED BY name ASC")

テーブルコンパクションを有効にします (デフォルトで有効になっていますが、このデモの最初に無効化しました)。

aws s3tables put-table-maintenance-configuration --table-bucket-arn ${S3TABLE_BUCKET_ARN} --namespace testnamespace --name testtable --type icebergCompaction --value "status=enabled,settings={icebergCompaction={strategy=sort}}"

有効にしたら、次のコンパクションジョブがトリガーされるのを待ちます。十分な数の小さなファイルが存在する場合、ジョブは一日中実行されます。コンパクションステータスは、次のコマンドを使用して確認できます。

aws s3tables get-table-maintenance-job-status --table-bucket-arn ${S3TABLE_BUCKET_ARN} --namespace testnamespace --name testtable

コンパクションが完了したら、テーブルを構成するファイルをもう一度調べます。データが 2 つのファイルにコンパクションされており、上限値と下限値がこれら 2 つのファイル全体でデータがソートされたことを示しています。

spark.sql("""
  SELECT 
    substring_index(file_path, '/', -1) as file_name,
    record_count,
    file_size_in_bytes,
    CAST(UNHEX(hex(lower_bounds[2])) AS STRING) as lower_bound_name,
    CAST(UNHEX(hex(upper_bounds[2])) AS STRING) as upper_bound_name
  FROM ice_catalog.testnamespace.testtable.files
  ORDER BY file_name
""").show(20, false)
+------------------------------------------------------------+------------+------------------+----------------+----------------+
|file_name                                                   |record_count|file_size_in_bytes|lower_bound_name|upper_bound_name|
+------------------------------------------------------------+------------+------------------+----------------+----------------+
|00000-4-51c7a4a8-194b-45c5-a815-a8c0e16e2115-0-00001.parquet|13195713    |50034921          |Anjali          |Kelly           |
|00001-5-51c7a4a8-194b-45c5-a815-a8c0e16e2115-0-00001.parquet|10804307    |40964156          |Liza            |Tom             |
+------------------------------------------------------------+------------+------------------+----------------+----------------+

ファイルの数が少なく、ファイルのサイズが大きくなっていて、指定したソート列全体でクラスタリングが改善されています。

z-order の使用にも同じ手順を実行しますが、その場合はメンテナンス設定で strategy=z-order を設定します。

利用可能なリージョン
Sort コンパクションと z-order コンパクションは、Amazon S3 Tables がサポートされるすべての AWS リージョンで利用でき、AWS Glue データカタログによる最適化が利用可能な汎用 S3 バケットにも利用できます。S3 Tables に関しては、既存の使用量とメンテナンス料金以外の追加料金はかかりません。データカタログによる最適化に関しては、コンパクション時にコンピューティング料金が適用されます。

これらの変更により、sort 列または z-order 列でフィルタリングするクエリは、より高速なクエリ時間とエンジンコストの削減からメリットを得られます。私の経験では、binpack から sort または z-order に切り替えるときに、データレイアウトとクエリパターンに応じて、3 倍以上のパフォーマンス向上を確認できました。実際のデータでパフォーマンスがどれだけ向上したかをぜひ教えてください。

詳細については、Amazon S3 Tables の製品ページにアクセスするか、「S3 Tables のメンテナンス」ドキュメントをご覧ください。S3 Tables API または AWS Glue による最適化を使用して、今すぐ独自のテーブルで新しい戦略のテストを開始することも可能です。

– seb

原文はこちらです。