Spark 宣言型パイプライン
Spark 宣言型パイプライン (SDP) は、AWS Glue 6.0 でバッチおよびストリーミングデータパイプラインを構築するための宣言型フレームワークです。SDP では、SQL または Python を使用してデータの外観を定義すると、フレームワークが自動的に実行プランを決定し、データセット間の依存関係を解決し、独立したブランチを並行実行します。
SDP は、読み取り、書き込み、カタログ登録、実行順序付けのための命令型のボイラープレートコードを排除することで、パイプライン開発を簡素化します。フレームワークがパイプラインインフラストラクチャに対処するため、ユーザーはビジネストランスフォーメーションに集中することができます。
SDP は、AWS Glue バージョン 6.0 以降で有効です。
SDP の概念
パイプラインは、YAML マニフェストファイル (spark-pipeline.yml) と、1 つ以上の SQL または Python 変換ファイルで構成されます。SDP は自動的に以下を行います。
-
テーブル参照から DAG を推測して依存関係を解決する
-
手動オーケストレーションなしで実行順序を決定する
-
独立したブランチを並行して実行してスループットを最大化する
-
チェックポイントを介したストリーミングテーブルの増分状態を管理する
-
マテリアライズ時にカタログに出力テーブルを登録する
データセットタイプ
SDP では、以下の 3 つのデータセットタイプを使用できます。
- ストリーミングテーブル
-
最後の実行以降の新しいデータのみを処理します。チェックポイントを使用してジョブ実行全体の状態を維持します。ストリーミングテーブルは、取り込み、イベントストリーム、IoT データ、変更データキャプチャ、追加のみのソースに使用します。
- マテリアライズドビュー
-
実行のたびにデータセットを完全に再計算します。出力は、常にソースデータの現在の状態を反映します。集計、結合、概要分析、レポートにマテリアライズドビューを使用します。
- 一時ビュー
-
セッションスコープであり、永続化またはカタログ化されません。中間変換とステージングロジックには一時ビューを使用します。
重要
現在のバージョンでは、マテリアライズドビューが常に完全に再計算されます。増分更新はサポートされていません。増分ワークロードには、ストリーミングテーブルを使用します。
前提条件
SDP を使用するには、以下が必要です。
-
AWS Glue バージョン 6.0
-
パイプラインストレージ用の Amazon S3 の場所 (チェックポイント、メタデータ)
-
データカタログ統合の場合 (オプション):
--enable-glue-datacatalogをtrueに設定します。または、Spark 設定でカタログ設定を直接設定することもできます。 -
永続テーブルストレージの場合:
spark.sql.warehouse.dirを Amazon S3 パスに設定するか、パイプライン YAML のdatabase:フィールドを設定し、AWS Glue データベースに Amazon S3 パスまで設定されたLocationUriがあることを確認します -
ストリーミングテーブルを使用したクロスラン増分処理の場合: Iceberg テーブルを使用します (Hive マネージドストリーミングテーブルはクロスラン増分処理をサポートしていません)
重要
パイプライン YAML で database: フィールドを使用する場合、対応する AWS Glue データベースの LocationUri を Amazon S3 パスに設定する必要があります。多くの場合、コンソールを使用して作成されたデータベースには、空の LocationUri があります。明示的な Amazon S3 の場所を使用してデータベースを作成または更新します。
aws glue create-database --database-input '{ "Name":"my_pipeline_db", "LocationUri":"s3://my-bucket/warehouse/my_pipeline_db" }'
パイプラインの作成
SDP パイプラインを作成するには、次のステップを完了します。
ステップ 1: パイプライン YAML を作成する
spark-pipeline.yml という名前のファイルを作成します:
name: my_analytics_pipeline catalog: spark_catalog database: analytics_db storage: s3://my-bucket/pipeline-storage/ libraries: - glob: include: transformations/** configuration: spark.sql.shuffle.partitions: "4"
次の表は、パイプライン YAML フィールドを示しています。
| フィールド | 必要 | 説明 |
|---|---|---|
name |
はい | パイプラインの名前。 |
catalog |
いいえ | 使用するカタログ。デフォルトは spark_catalog です。 |
database |
いいえ | 出力テーブルのターゲットデータベース。データベースが存在し、LocationUri が設定されている必要があります。 |
storage |
はい | パイプラインチェックポイントとメタデータ用の Amazon S3 パス。 |
libraries |
はい | 含める変換ファイルの glob パターン。 |
configuration |
いいえ | Spark 設定プロパティ。 |
ステップ 2: 変換を記述する
transformations/ ディレクトリに変換ファイルを作成します。SQL、Python、またはその両方を同じパイプラインで使用できます。
SQL の例 (transformations/silver.sql):
CREATE MATERIALIZED VIEW silver_sales AS SELECT *, UPPER(region) as clean_region FROM bronze_sales WHERE amount > 0; CREATE MATERIALIZED VIEW gold_summary AS SELECT clean_region, COUNT(*) as order_count, SUM(amount) as total_revenue FROM silver_sales GROUP BY clean_region;
Python の例 (transformations/bronze.py):
from pyspark import pipelines as dp from pyspark.sql import DataFrame, SparkSession spark = SparkSession.active() @dp.materialized_view(comment="Raw sales data from S3") def bronze_sales() -> DataFrame: return spark.read.format("csv").option("header", "true") \ .option("inferSchema", "true") \ .load("s3://source-bucket/raw-data/sales/")
Python ストリーミングテーブルの例 (transformations/events.py):
from pyspark import pipelines as dp from pyspark.sql import DataFrame, SparkSession spark = SparkSession.active() dp.create_streaming_table( "streaming_events", comment="Incremental event ingestion", schema="event_id STRING, event_type STRING, timestamp LONG, payload STRING" ) @dp.append_flow(target="streaming_events") def ingest_events() -> DataFrame: return ( spark.readStream.format("json") .schema("event_id STRING, event_type STRING, timestamp LONG, payload STRING") .load("s3://source-bucket/events/") )
注記
Python でテーブルをストリーミングする場合、dp.create_streaming_table() と @dp.append_flow(target=...) を組み合わせて使用します。@dp.streaming_table デコレータは使用できません。
ステップ 3: Amazon S3 にアップロードする
次のいずれかの方法で、パイプラインファイルを Amazon S3 にアップロードします。
-
spark-pipeline.ymlとtransformations/ディレクトリを含む.zipファイル -
同じ構造を含む Amazon S3 プレフィックス (ディレクトリ)
ステップ 4: AWS Glue ジョブを作成して実行する
以下のパラメータを使用して AWS Glue ジョブを作成します。
-
--enable-spark-declarative-pipeline:true(必須 — SDP モードをアクティブ化) -
ScriptLocation: パイプライン定義 zip または Amazon S3 プレフィックス (SDP パイプラインに必要) -
--enable-glue-datacatalog:true(オプション — データカタログにテーブルを登録)
以下の例では、AWS CLI を使用して SDP ジョブを作成します。
aws glue create-job \ --name my-sdp-pipeline \ --role arn:aws:iam::123456789012:role/MyGlueRole \ --glue-version 6.0 \ --worker-type G.1X --number-of-workers 2 \ --command '{"Name":"glueetl","ScriptLocation":"s3://my-bucket/pipelines/my_pipeline.zip"}' \ --default-arguments '{ "--enable-spark-declarative-pipeline": "true", "--enable-glue-datacatalog": "true" }'
パイプラインの実行
StartJobRun を使用して SDP パイプラインを実行します。実行時に渡されたジョブ引数を使用して、実行動作を制御できます。
実行モード
パイプラインの実行を制御するには、以下の引数を StartJobRun に渡します。
--conf spark.glue.sdp.jobMode-
実行モードの制御:
RUN(デフォルト) — パイプラインを正常に実行します。VALIDATE— データを書き込まずに YAML 構文、依存関係の解決、SQL/Python のコンパイルをチェックするドライランを実行します。
--conf spark.glue.sdp.runMode-
更新するデータセットを制御します。
--refresh-
すべてのデータセットを実行します。マテリアライズドビューが完全に再計算されます。ストリーミングテーブルは、最後のチェックポイント以降の新しいデータのみを処理します。
--refresh <dataset_name>-
指定されたデータセットのみを実行します。ストリーミングテーブルの場合、新しいデータを増分処理します。マテリアライズドビューの場合、そのビューのみの完全な再計算を実行します。
--full-refresh-
すべてのデータセットをリセットして再計算します。ストリーミングテーブルの場合、チェックポイントをリセットし、すべてのデータを最初から再処理します。
--full-refresh-all-
すべてのテーブルを削除し、パイプライン全体をゼロから再処理します。
SDP での Iceberg テーブルの使用
クロスラン増分処理が必要なストリーミングテーブルの場合は、Apache Iceberg を使用します。Hive マネージドストリーミングテーブルは、メタデータをローカルに保存し、複数のジョブの実行をまたいで保持されることはありません。
Iceberg を設定するには、spark-pipeline.yml 設定セクションに以下を追加します。
configuration: spark.sql.catalog.spark_catalog: "org.apache.iceberg.spark.SparkSessionCatalog" spark.sql.catalog.spark_catalog.type: "hadoop" spark.sql.catalog.spark_catalog.warehouse: "s3://my-bucket/iceberg-warehouse"
Iceberg を設定すると、以下の利点があります。
-
ストリーミングテーブルはジョブ実行全体で Amazon S3 のチェックポイント状態を維持する
-
各実行で新しいデータファイルと Iceberg スナップショットが作成される
-
後続の実行は、最後にコミットされたオフセットから再開される
-
完全なテーブル履歴が Iceberg のスナップショットメカニズムを通じて保持される
考慮事項と制限事項
SDP を使用する場合は、以下を考慮してください。
-
マテリアライズドビューは常に完全に再計算されます — 増分更新はサポートされていません。増分ワークロードには、ストリーミングテーブルを使用します。
-
ストリーミングテーブル Python API —
dp.create_streaming_table()と@dp.append_flow(target=...)を使用します。@dp.streaming_tableデコレータは、現在のバージョンでは利用できません。 -
クロスラン増分処理には Iceberg が必要です — Hive または AWS Glue マネージドカタログを使用するストリーミングテーブルでは、複数のジョブの実行をまたぐ増分処理はサポートされません。永続的な増分状態には Iceberg テーブルを使用します。
-
Database LocationUri 必須 — パイプライン YAML で
database:を指定する場合、AWS Glue データベースのLocationUriを Amazon S3 パスに設定する必要があります。設定していないと、パイプラインは失敗します。 -
データ品質の期待 — インラインデータ品質アノテーションは、現在の SDP フレームワークではサポートされていません。
-
ダウンストリームクエリ関数での
withColumnの回避 — ダウンストリームデータセット (マテリアライズドビューなど) がspark.table(...)を使用してアップストリームパイプラインデータセットから読み取り、.withColumn(...)を適用する場合、SDP が 2 回目以降の実行でデータセット間の依存関係を検出できない可能性があります。これにより、ダウンストリームは前回の実行から古いデータを読み取ることになります (1 回分の遅延)。この問題を回避するには、.select(...)を使用する代わりに、派生した列を.withColumn(...)内で表現します。また、クエリ関数内でプラン解決 (.schemaまたは.collectなど) を強制するオペレーションは避けてください。 -
移行ツールなし — 他のパイプラインフレームワークからの自動移行はサポートされていません。テーブルを段階的に移行 — SDP は既存のカタログテーブルから読み取ることができます。
-
スケジューリング — SDP ジョブは、他の AWS Glue ジョブ (AWS Glue トリガー、Amazon EventBridge、Apache Airflow) と同じスケジューリングメカニズムを使用します。
命令スクリプトから SDP への移行
既存の命令的な Spark スクリプトを SDP に段階的に移行できます。
-
1 つのテーブルから開始 — 1 回の
spark.sql(...).write.saveAsTable(...)呼び出しをCREATE MATERIALIZED VIEWSQL ステートメントに変換します。 -
テーブルを段階的に追加 — SDP は混合依存関係を処理します。SDP テーブルは、パイプラインに含まれていない既存のカタログテーブルから読み取ることができます。
-
移行中に両方のパターンを並行して実行 — SDP ジョブと命令的ジョブは共存できます。
SDP は、既存のデータカタログテーブル、外部テーブル、クロスデータベース参照など、SparkSession を介してアクセス可能な任意のテーブルを参照できます。