注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
Foundry の Iceberg カタログは標準の Iceberg を拡張し、各ブランチが独自の現在のスキーマ、デフォルトのパーティション仕様、およびデフォルトの並べ替え順序を個別に追跡できるようにしています。これらの操作は、実行対象のブランチに分離され、テーブルの main(master)ブランチやその他のブランチには影響しません。これにより、Iceberg テーブルは Iceberg REST カタログ仕様 ↗ に準拠しながら、ブランチでの作業が完全に分離されるという、Foundry ユーザーがカタログデータセットで慣れ親しんでいる動作と一致します。
このページでは、ブランチ分離の仕組み、デフォルトの Iceberg の動作をどのように拡張するか、および Foundry 内で Iceberg を使用する際にどのように自動適用されるかを説明します。また、外部の Iceberg クライアントを使用する際に、この動作を有効にする方法も説明します。
このページで説明するブランチ分離は、Foundry のビルドシステムを通じてジョブを実行する際に適用されます。外部クライアントから Foundry の Iceberg カタログに書き込む場合、デフォルトでは標準の Iceberg のブランチ動作が適用されます。Foundry のブランチ分離を有効にする方法を含め、詳細は外部クライアントでブランチを使用するを参照してください。
Foundry でビルドを実行すると、Foundry は Iceberg テーブルに対してブランチ分離を提供します。つまり、Foundry はスキーマ、パーティション仕様、および並べ替え順序の変更を関連するブランチに自動的に分離し、ブランチに限定されたこれらの変更によって、ほかのブランチが意図せず変更されることを防ぎます。これを設定するためにユーザーが何か操作する必要はありません。これは、Foundry のビルドシステムを使用して Iceberg テーブルに書き込む際のデフォルトの動作です。
Foundry は、ブランチ単位のスキーマ、パーティション仕様、および並べ替え順序を、テーブルの Iceberg メタデータファイル内の追加プロパティとして保存します。例:"foundry.branch.feature-branch.schema-id" : "3"。
標準の Iceberg では、スキーマはすべてのブランチで共有されるテーブルレベルの概念であり、テーブル全体で単一の現在のスキーマが追跡されます。詳細は Apache Iceberg のドキュメント ↗ を参照してください。つまり、どのブランチでテーブルのスキーマを変更しても、main とその他すべてのブランチのスキーマが変更されます。
すべてのブランチで単一のスキーマを共有していると、本番環境にマージする前に、ブランチ上でスキーマの変更を分離して開発または検証することが難しくなります。ブランチ上でスキーマの変更をテストするには、テーブルのグローバルスキーマを変更する必要があります。このような変更は、どのブランチで行われたかに関係なく、main 上のテーブルを利用するすべてのコンシューマーに即座に影響します。
Foundry の Iceberg カタログは、ブランチ単位のスキーマ、パーティション仕様、および並べ替え順序を自動的に追跡することで、この問題を解決します。ブランチ(たとえば my-branch)上で実行されるジョブが参照するのは、そのブランチが追跡しているスキーマであり、main 上のスキーマではありません。my-branch 上のそのジョブ内で行われたスキーマの変更は、関連するブランチ(この場合は my-branch)に保存され、main 上の現在のスキーマはまったく変更されません。
次のテーブルは、ブランチ単位で管理されるものと、テーブル単位で管理され、すべてのブランチで共有されるものをまとめたものです。
| メタデータ | Foundry による拡張ブランチ機能 | デフォルトの Iceberg ブランチ機能 |
|---|---|---|
| スキーマ履歴 | テーブル単位 | テーブル単位 |
| テーブルプロパティ | テーブル単位 | テーブル単位 |
| 現在のスナップショット | ブランチ単位 | ブランチ単位 |
| 現在のスキーマ | ブランチ単位 | テーブル単位 |
| デフォルトのパーティション仕様 | ブランチ単位 | テーブル単位 |
| デフォルトの並べ替え順序 | ブランチ単位 | テーブル単位 |
Foundry による拡張ブランチ機能では、現在のスキーマはブランチ単位で管理されますが、スキーマの履歴はテーブル単位で管理されます。つまり、ブランチで新しい列を追加すると、そのスキーマはテーブルの共有スキーマリストに追加されますが、main 上の現在のスキーマとしては設定されません。
Foundry のビルドシステムでブランチ上のジョブが実行されると、Foundry はそのジョブのすべてのカタログ操作にブランチコンテキストを自動的に挿入します。ユーザーが何か設定する必要はありません。パイプラインは、追加のコードなしで、そのブランチを対象に入力を読み取り、出力を書き込みます。
以下の例では、最も一般的な2つのシナリオを示します。ブランチ上で新しいテーブルを作成する場合と、ブランチ上で既存のテーブルのスキーマを変更する場合です。
開発ブランチ feature/customer-scores 上で新しいテーブルを作成しているとします。トランスフォームは出力用の Iceberg テーブルを作成し、初期データを書き込みます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14import pyarrow as pa from transforms.api import transform from transforms.tables import IcebergOutput, TableOutput @transform.using(customer_scores=TableOutput("/<path>/customer_scores")) def compute(customer_scores: IcebergOutput): data = pa.table( { "customer_id": pa.array([1, 2, 3], type=pa.int64()), "score": pa.array([0.91, 0.74, 0.88], type=pa.float64()), } ) customer_scores.write_table(data)
フィーチャーブランチで書き込んだ後の customer_scores テーブルの状態は次のとおりです。
| Foundry による拡張ブランチ機能 | デフォルトの Iceberg ブランチ機能 | |
|---|---|---|
feature/customer-scores 上のスキーマ | 新しいスキーマ | 新しいスキーマ |
main 上のスキーマ | 空 | 新しいスキーマ |
feature/customer-scores 上のデータ | あり | あり |
main 上のデータ | なし | なし |
Foundry のブランチ分離を使用する場合: ブランチが初期スキーマとスナップショットを保持します。テーブルは main 上に存在しますが、スキーマは空でデータはありません。
デフォルトの Iceberg ブランチを使用する場合: ブランチのスキーマが main 上にも反映されます。
今度は、テーブル customer_scores がすでに本番環境に存在しているとします。パイプラインへの変更を検討してテストしており、ブランチ feature/scoring-v2 上で実行するジョブの一部として、新しい列を追加し、既存の列のデータ型を変更したいとします。その際、下流の本番環境のコンシューマーが main 上で参照する内容には影響を与えないようにします。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17import pyarrow as pa from transforms.api import transform from transforms.tables import IcebergOutput, TableOutput @transform.using( customer_scores=TableOutput("/<path>/customer_scores") ) def compute(customer_scores: IcebergOutput): data = pa.table( { "customer_id": pa.array(["c1", "c2", "c3"], type=pa.string()), "score": pa.array([0.91, 0.74, 0.88], type=pa.float64()), "score_v2": pa.array([0.95, 0.80, 0.92], type=pa.float64()), } ) customer_scores.write_table(data)
feature/scoring-v2 上でジョブを実行した後のテーブルの状態は次のとおりです。
| Foundry による拡張ブランチ機能 | デフォルトの Iceberg ブランチ機能 | |
|---|---|---|
feature/scoring-v2 上のスキーマ | 新しいスキーマ | 新しいスキーマ |
main 上のスキーマ | 古いスキーマ | 新しいスキーマ |
feature/scoring-v2 上のデータ | あり | あり |
main 上のデータ | 変更なし | 変更なし |
Foundry のブランチ分離を使用する場合: 新しい列とデータ型の変更は、そのブランチに分離されます。main は元のスキーマを保持するため、下流のコンシューマーは影響を受けません。
デフォルトの Iceberg ブランチを使用する場合: ブランチと main は単一の現在のスキーマを共有するため、書き込み時のスキーマ検証に失敗するか、main のスキーマを更新する必要が生じ、その変更が下流のコンシューマーに反映されます。
Foundry の Iceberg カタログは、Iceberg REST カタログ仕様 ↗に完全に準拠しています。
外部ツールから Foundry の Iceberg カタログにアクセスする場合、カタログの動作は X-PLTR-Branch ヘッダーが設定されているかどうかによって異なります。外部クライアントでブランチを扱う場合は、Foundry のブランチ動作の一貫性を確保するために、X-PLTR-Branch ヘッダーを設定してください。
X-PLTR-Branch ヘッダーが設定されている場合:
main が参照されている場合)、デフォルトで X-PLTR-Branch ヘッダーに設定されたブランチが使用されます。リクエストで特定の(main 以外の)ブランチが指定されている場合は、ヘッダーのブランチではなく、そのブランチが使用されます。たとえば、ヘッダーが featurebranch1 に設定されている場合、SELECT * FROM table と SELECT * FROM table.branch_main は featurebranch1 を参照しますが、SELECT * FROM table.branch_featurebranch2 は featurebranch2 を参照します。X-PLTR-Branch ヘッダーが設定されていない場合、Iceberg のデフォルトの動作が適用されます。
SELECT * FROM table VERSION AS OF <snapshot_id>。main のスキーマ(テーブルスコープ)が使用されます。例:SELECT * FROM table.branch_my_branch。main のスキーマ(テーブルスコープ)に照らして検証されます。スキーマに準拠しない書き込みは、ブランチに合わせて調整されるのではなく、失敗します。main のテーブルスコープのスキーマに適用され、ブランチ内に分離されません。X-PLTR-Branch ヘッダーを設定するPyIceberg クライアントのブランチを設定するには、カタログプロパティにヘッダーを追加します。
Copied!1 2 3 4 5 6 7 8 9 10from pyiceberg.catalog import load_rest catalog = load_rest( "foundry", { "uri": "https://your.foundry/iceberg", "token": "eyJwb...", "header.X-PLTR-Branch": "my-branch" }, )
Spark では、カタログの設定プロパティとしてヘッダーを渡します。
Copied!1 2 3 4 5 6 7spark = ( SparkSession.builder ... .config("spark.sql.catalog.foundry.header.X-PLTR-Branch", "my-branch") ... .getOrCreate() )
外部クライアントを Foundry のカタログに接続する方法の詳細については、Iceberg クライアントを認証すると例: Local Jupyterを参照してください。
ブランチ分離を使用する際は、以下の点に注意してください。
ジョブがブランチ上で実行される場合、そのブランチのコンテキストは、ジョブが読み取りと書き込みを行うすべてのテーブルに一律に適用されます。現在、同じジョブ内で入力テーブルや出力テーブルごとに異なるブランチを設定することはできません。Foundry は、解決されたすべての入力ブランチがジョブのブランチと一致することを検証し、一致しない場合はエラーを発生させます。
ブランチが特定のスキーマまたはパーティション仕様を追跡している場合、main 上で実行される操作であっても、そのスキーマまたは仕様をテーブルから削除することはできません。これにより、並行して実行されるクリーンアップやメンテナンス操作によって、気付かないうちにブランチが破損することを防ぎます。この保護は、ブランチが削除されると自動的に解除されます。
チェリーピックやファストフォワードなど、Iceberg 標準のブランチマージ手続きは、スナップショット参照のみを操作し、Foundry のブランチスコープのスキーマプロパティを認識しません。これらの手続きを使用してブランチを main にマージしても、ブランチのスキーマは引き継がれず、main は既存のスキーマを保持します。ブランチでのスキーマ変更を main に確実に反映するには、コードをマージし、Foundry のビルドシステムを使用して main 上で再ビルドします。
一部の特権 REST エンドポイントは Foundry のブランチから呼び出すことができません。主なものは以下のとおりです。
dropNamespaceupdateNamespacedropTablerenameTablecommitTransactioncreateViewdropViewrenameViewブランチ分離は、transforms-tables ライブラリのバージョン 0.1211.0 以降で利用可能です。