ゼロ ETL 統合のデータパーティショニング
データパーティショニングとは
データパーティショニングは、大きなデータセットをパーティションと呼ばれるより小さく管理しやすいセグメントに分割する手法です。AWS Glue ゼロ ETL 統合のコンテキストでは、パーティション分割は、特定の列の値またはそれらの値の変換に基づいて、ターゲット位置にデータを整理します。
データパーティショニングの利点
効果的なデータパーティショニングを分析ワークロードで使用すると、主に次のような利点があります。
-
クエリパフォーマンスの向上: クエリは無関係なパーティションをスキップ (パーティションプルーニング) するため、スキャンする必要があるデータの量を減らすことができます。
-
コストの削減: スキャンするデータを減らすことで、分析クエリのコンピューティングコストと I/O コストを低減できます。
-
スケーラビリティの向上: パーティション分割によってデータセグメントの並列処理が可能になり、分析ワークロードをより効率的にスケーリングできます。
-
データライフサイクル管理の簡素化: 保持ポリシーをパーティションレベルで管理できるため、古いデータのアーカイブや削除が容易になります。
主要なパーティショニングの概念
- パーティション列
-
レコードがどのようにパーティションに編成されるかを決定するために使用されるデータの列。有効なパーティション列は、一般的なクエリパターンと一致し、適切なカーディナリティを持つ必要があります。
- パーティション関数
-
実際のパーティション境界を作成するためにパーティション列の値に適用される変換。例として、アイデンティティ (raw 値を使用)、時間ベースの関数 (年、月、日、時間)、バケット化などがあります。
- パーティションプルーニング
-
クエリに関連するデータを含まないパーティションをクエリエンジンが識別してスキップするプロセス。これにより、パフォーマンスが大幅に向上します。
- パーティションの粒度
-
データパーティショニングの詳細レベル。より細かい粒度 (より多くのパーティション) にすると、クエリのパフォーマンスは向上しますが、メタデータのオーバーヘッドが増加する可能性があります。より粗い粒度 (より少ないパーティション) にすると、メタデータのオーバーヘッドは軽減されますが、必要以上に多くのデータがスキャンされる可能性があります。
AWS Glue ゼロ ETL 統合でのパーティショニング
AWS Glue ゼロ ETL 統合では、高度なパーティショニング機能を提供する Apache Iceberg テーブル形式を使用します。ゼロ ETL 統合を作成すると、以下を行うことができます。
-
データソースに最適化されたデフォルトパーティショニング戦略を使用する
-
クエリパターンに応じたカスタムパーティショニング仕様を定義する
-
変換をパーティション列に適用する (特にタイムスタンプベースのパーティショニングに役立つ)
-
複数のパーティション戦略を組み合わせてマルチレベルパーティショニングを行う
パーティショニングの設定は、ゼロ ETL 統合を設定するときに CreateIntegrationTableProperty
API を通じて指定されます。設定すると、AWS Glue はこれらのパーティショニング戦略を自動的に適用して、ターゲットの場所にデータを整理します。
パーティション仕様の API リファレンス
CreateIntegrationTableProperties API で次のパラメータを使用し、パーティショニングを設定します。
- PartitionSpec
-
ターゲットロケーションでデータがパーティショニングされる法を定義するパーティション仕様の配列。
{ "partitionSpec": [ { "fieldName": "timestamp_col", "functionSpec": "month", "conversionSpec": "epoch_milli" }, { "fieldName": "category", "functionSpec": "identity" }, { "fieldName": "user_id", "functionSpec": "bucket", "bucketCount": 16 }, { "fieldName": "product_code", "functionSpec": "truncate", "width": 4 } ] }
- FieldName
-
パーティショニングに使用する列名を指定する UTF-8 文字列 (1~128 バイト)。
- FunctionSpec
-
パーティショニング関数を指定します。有効な値:
identity
- 変換なしでソース値を直接使用するyear
- タイムスタンプ値から年を抽出する (例: 2023)month
- タイムスタンプ値から月を抽出する (例: 2023-01)day
- タイムスタンプ値から日を抽出する (例: 2023-01-15)hour
- タイムスタンプ値から時間を抽出する (例: 2023-01-15-14)bucket
- ハッシュベースのパーティショニングを使用して、指定された数のバケットに値を分散します。bucketCount
パラメータが必要です。truncate
- 文字列値を指定された幅に切り捨てます。width
パラメータが必要です。
注記
時間ベースの関数 (
year
、month
、day
、hour
) では、ソースタイムスタンプ形式を指定するConversionSpec
パラメータが必要です。bucket
とtruncate
関数には、説明に指定されている追加のパラメータが必要です。 - ConversionSpec
-
ソースデータのタイムスタンプ形式を指定する UTF-8 文字列。次の値を指定できます:
-
epoch_sec
– UNIX エポックタイムスタンプ (秒単位) -
epoch_milli
– UNIX エポックタイムスタンプ (ミリ秒単位) -
iso
– ISO 8601 形式のタイムスタンプ
-
- BucketCount
-
bucket
関数の使用時に作成するバケットの数を指定する整数。functionSpec
をbucket
に設定した場合、このパラメータは必須です。値は正の整数である必要があります。ハッシュベースのバケット化によって、指定された数のバケットに値が均等に分散されます。例 バケットパーティショニングの例
{ "partitionSpec": [ { "fieldName": "user_id", "functionSpec": "bucket", "bucketCount": 16 } ] }
- [幅]
-
truncate
関数の使用時に切り捨て幅を指定する整数。functionSpec
をtruncate
に設定した場合、このパラメータは必須です。値は、文字列値の先頭から保持される文字数を表す正の整数である必要があります。例 切り捨てパーティショニングの例
{ "partitionSpec": [ { "fieldName": "product_code", "functionSpec": "truncate", "width": 4 } ] }
パーティショニング戦略
デフォルトのパーティショニング
パーティション列が指定されていない場合、AWS Glue Zero-ETL はデータソースに最適化されたデフォルトのパーティショニング戦略を適用します。
-
プライマリキーベースのパーティショニング: プライマリキーを持つソース (DynamoDB テーブルなど) の場合、AWS Glue Zero-ETL はプライマリキーとバケット化によってデータを自動的にパーティショニングし、パーティションの爆発を防ぎます。
デフォルトのパーティショニングは、手動で設定しなくても、一般的なクエリパターンが適切に機能するように設計されています。ただし、特定のクエリパターンやパフォーマンス要件には、カスタムパーティショニング戦略を定義することをお勧めします。
ユーザー定義のパーティショニング戦略
AWS Glue Zero-ETL では、PartitionSpec
パラメータを使用してカスタムパーティショニング戦略を定義できます。1 つ以上のパーティション列を指定し、各列に異なるパーティショニング関数を適用できます。
ID パーティショニングは、列の raw 値を使用してパーティションを作成します。この戦略は、カテゴリ、リージョン、ステータスフィールドなど、低から中程度のかーディナリティを持つ列に役立ちます。
例 ID パーティショニングの例
{ "partitionSpec": [ { "fieldName": "category", "functionSpec": "identity" } ] }
これにより、「カテゴリ」列の一意の値ごとに個別のパーティションが作成されます。
警告
高カーディナリティ列 (プライマリキーやタイムスタンプなど) では ID パーティショニングを使用しないでください。使用すると、パーティションの爆発が発生して、パフォーマンスが低下し、メタデータのオーバーヘッドが増加する可能性があります。
時間ベースのパーティショニングは、さまざまな粒度 (年、月、日、または時間) のタイムスタンプ値に基づいてデータを整理します。この戦略は時系列データに最適であり、効率的な時間範囲クエリを実行可能にします。
時間ベースのパーティショニングを使用する場合、AWS Glue ゼロ ETL はパーティション関数を適用する前に、さまざまなタイムスタンプ形式を標準化された形式に自動的に変換できます。この変換は、ConversionSpec
パラメータを使用して指定します。
例 時間ベースのパーティショニングの例
{ "partitionSpec": [ { "fieldName": "created_at", "functionSpec": "month", "conversionSpec": "epoch_milli" } ] }
この関数は、Unix エポックタイムスタンプをミリ秒単位で含む「created_at」列に基づいてデータを月単位でパーティショニングします。
AWS Glue ゼロ ETL は、次の時間ベースのパーティション関数をサポートしています。
-
year: 年別にデータをパーティショニング (例: 2023、2024)
-
month: データを月別にパーティショニング (例: 2023-01、2023-02)
-
day: データを日別にパーティショニング (例: 2023-01-01、2023-01-02)
-
hour: データを時間単位でパーティショニング (例: 2023-01-01-01、2023-01-01-02)
AWS Glue ゼロ ETL は、ConversionSpec
パラメータで以下のタイムスタンプ形式をサポートしています。
-
epoch_sec: 秒単位の Unix エポックタイムスタンプ
-
epoch_milli: ミリ秒単位の Unix エポックタイムスタンプ
-
iso: ISO 8601 形式のタイムスタンプ
注記
元の列値はソースデータ内で変更されません。AWSGlue はターゲットデータベースのテーブルで、パーティション列の値のみをタイムスタンプタイプに変換します。変換は、パーティショニングプロセスのみに適用されます。
バケットパーティショニングでは、ハッシュベースのディストリビューションを使用して、固定数のバケットにデータを均等に分散します。この戦略は、パーティションの数を制御してデータを均等に分散する高カーディナリティ列に役立ちます。
例 バケットパーティショニングの例
{ "partitionSpec": [ { "fieldName": "user_id", "functionSpec": "bucket", "bucketCount": 16 } ] }
これにより、「user_id」列のハッシュ値に基づいて 16 個のバケットが作成され、実際のユーザー ID 値に関係なく均等に分散されます。
バケットパーティショニングは、以下に対して特に効果的です。
-
ユーザー ID、セッション ID、プライマリキーなどの高カーディナリティ列
-
予測可能なパーティション数が必要なシナリオ
-
固定パーティション境界全体で並列処理が有益なワークロード
切り捨てパーティショニングは、切り捨てられた文字列値に基づいてパーティションを作成し、最初の N 文字のみを保持します。この戦略は、類似した値をグループ化する文字列の列に役立ちます。
例 切り捨てパーティショニングの例
{ "partitionSpec": [ { "fieldName": "product_code", "functionSpec": "truncate", "width": 4 } ] }
これにより、「product_code」列の最初の 4 文字に基づいてパーティションが作成されます。たとえば、「ELEC12345」と「ELEC67890」は、同じ「ELEC」パーティションにグループ化されます。
切り捨てパーティショニングは、以下に対して特に効果的です。
-
製品コード、SKU、または意味のあるプレフィックスを持つその他の構造化識別子
-
地域グループ化が有益な地域コードまたは郵便番号
-
プレフィックスベースのグループ化がクエリパターンと一致する文字列の列
マルチレベルパーティショニングは、複数のパーティション戦略を組み合わせて階層パーティショニングスキームを作成します。これは、同じデータセットに対してさまざまなタイプのクエリを最適化するのに役立ちます。
例 マルチレベルパーティショニングの例
{ "partitionSpec": [ { "fieldName": "created_at", "functionSpec": "month", "conversionSpec": "iso" }, { "fieldName": "region", "functionSpec": "identity" }, { "fieldName": "user_id", "functionSpec": "bucket", "bucketCount": 8 } ] }
この関数は、3 レベルのパーティショニングスキームを作成します。最初は月ごと (「created_at」列から)、次にリージョンごと、最後にユーザー ID バケットごとに作成します。これにより、日付範囲、特定の地域、ユーザーセグメント、またはこれらのディメンションの任意の組み合わせでフィルタリングする効率的なクエリが実行可能になります。
マルチレベルパーティショニングスキームを設計する際は、次の点を考慮してください。
-
パーティション階層の最初に選択性の高い列を配置する
-
パーティションの粒度とパーティション数のバランスを取る
-
パーティション分割スキームを最も一般的なクエリパターンに合わせる
ベストプラクティス
パーティション列の選択
-
identity
パーティション関数を持つ高カーディナリティ列を使用しないでください。ID パーティショニングを持つ高カーディナリティ列を使用すると、小さなパーティションが多く作成され、取り込みパフォーマンスが大幅に低下する可能性があります。高カーディナリティ列には次のものが含まれる場合があります。-
プライマリキー
-
タイムスタンプフィールド (
LastModifiedTimestamp
やCreatedDate
など) -
システム生成されたタイムスタンプ
-
-
同じ列で複数のタイムスタンプパーティションを選択しないでください。例:
"partitionSpec": [ {"fieldName": "col1", "functionSpec": "year", "conversionSpec" : "epoch_milli"}, {"fieldName": "col1", "functionSpec": "month", "conversionSpec" : "epoch_milli"}, {"fieldName": "col1", "functionSpec": "day", "conversionSpec" : "epoch_milli"}, {"fieldName": "col1", "functionSpec": "hour", "conversionSpec" : "epoch_milli"} ]
パーティション FunctionSpec/ConversionSpec の選択
-
タイムスタンプベースのパーティション関数を使用する際に、タイムスタンプベースのパーティショニングのために選択された列値の形式を表す正しい ConversionSpec (epoch_sec | epoch_milli | iso) を指定します。AWSGlue ゼロ ETL はこのパラメータを使用し、パーティショニングする前にソースデータをタイムスタンプ形式に正しく変換します。
-
データ量に基づいて適切な粒度 (年/月/日/時間) を使用します。
-
ISO タイムスタンプ を使用する際、タイムゾーンの影響を考慮してください。AWSGlue ゼロ ETL は、UTC タイムゾーンで選択したタイムスタンプ列のすべてのレコード値を入力します。
-
bucket
パーティショニングを使用する場合は、クエリ並列処理の要件に合ったバケット数を選択します。一般的なバケット数は 2 の累乗 (8、16、32) であり、最適なハッシュ分散が可能になります。 -
truncate
パーティショニングでは、データパターンに基づいて意味のあるグループ化を作成する幅の値を選択します。切り捨て幅が文字列値の重要なプレフィックス部分をキャプチャしていることを確認します。 -
bucket
またはtruncate
関数を非常に小さなデータセットの唯一のパーティション戦略として使用しないでください。不要なパーティションオーバーヘッドが発生する可能性があります。
エラー処理
NEEDS_ATTENTION 状態
統合は次の場合に NEEDS_ATTENTION 状態になります。
指定されたパーティション列がソースに存在しない場合
パーティション列のタイムスタンプ変換が失敗した場合