代表的な面接トピック

データエンジニアリング面接:OpenLineageイベントスキーマを安全に進化させるには?

データ難しい
Offer.cc 編集チーム公開日 更新日

質問

ダウンストリームのコンシューマーを壊すことなく、OpenLineageイベントスキーマをどのように進化させますか?

質問の概要と適用される場面

面接官は「ダウンストリームのコンシューマーを壊すことなく、OpenLineageイベントスキーマをどのように進化させますか?」と質問することがあります。これは、データプラットフォーム、データインフラストラクチャ、リネージシステムの職種に適した質問です。JSON Schema、Facet拡張、自動生成クライアント、イベントバージョン、コンシューマーの互換性をリリースプロセスに落とし込めるかどうかを評価します。

面接官が見ているポイント

重要なのはフィールド名を暗記することではなく、変更の境界線を認識することです。OpenLineageはその仕様をJSON Schemaとして文書化しており、既存のJSONファイルが変更された場合にはバージョンアップを要求します。JavaおよびPythonクライアントはそれから生成されます。また、面接官はRunEvent、JobEvent、DatasetEventの違いを区別できること、そしてカスタムFacetには一意のプレフィックスと不変のバージョニングされたスキーマURLが必要であることを知っているかを期待しています。

自身に問いかけるべき確認事項

その変更がコアオブジェクト、既存のFacet、または新しいカスタムFacetのいずれに影響するかを明確にします。どのプロデューサーがイベントを発行し、どのコンシューマーがそれをパースするのか?古いクライアント、リプレイジョブ、またはクロス言語SDKは存在するか?互換性の目標は、古いイベントの読み取り、バージョンのデュアルライト、または一度限りの切り替えのどれか?また、フィールドが必須か、オプションか、意味が変更されるのか、そして失敗したイベントがどのように処理されるかも確認します。

30秒の回答フレームワーク

5つのステップを使用します:

  1. プロデューサー、コンシューマー、イベントタイプ、現在のスキーマバージョンを棚卸しする。
  2. 既存のセマンティクスを変更するよりも、オプションフィールドまたは新しいFacetを優先する。
  3. バージョンを上げ、サンプルと自動生成クライアントを更新し、互換性マトリックスを作成する。
  4. リプレイとシャドウトラフィックで検証し、パース失敗や欠落フィールドを監視しながらプロデューサーをカナリアリリースする。
  5. 非推奨期間、ロールバックパス、コンシューマー移行の完了基準を設定する。

ステップごとの詳細な回答

1. イベントと依存関係の境界をマッピングする

OpenLineageオブジェクトモデルにはJobs、Runs、Datasetsが含まれます。RunEventは実行時状態を表し、JobEventとDatasetEventは設計時メタデータを表します。どのイベント、Facet、クライアントが影響を受けるかを確認します。変更がプロデューサーだけに留まらないよう、スキーマレポジトリ、生成されたコード、メッセージバス、インデックス、クエリAPIをマッピングします。

2. 互換性のある進化方法を選択する

オプションフィールドを追加することは、通常、既存フィールドの削除、型変更、再定義よりも安全です。意味が変わる場合は、新しいフィールドまたはFacetを追加し、一定期間デュアルライトを行います。衝突を避けるためにカスタムFacetにはプロジェクト固有のプレフィックスを使用します。同名のFacetはエンティティ上の以前のインスタンスを置き換えるため、名前とバージョンは安定している必要があります。

3. コード生成を伴うバージョン変更

OpenLineageでは、既存のJSON Schemaが変更されたときにファイルバージョンの引き上げが必要であり、バージョンURLは不変のバージョンを指す必要があります。JavaおよびPythonクライアントを生成し、そのテストを実行し、すべてのプロデューサーとコンシューマーが意図したバージョンに固定されていることを確認します。ドキュメントの更新や手動での型コピーだけで済ませてはなりません。

4. 互換性マトリックスを明示する

最低限、新しいプロデューサーと古いコンシューマー、古いプロデューサーと新しいコンシューマー、そしてリプレイデータに対する両バージョンのテストを行います。各フィールドについて、欠落する可能性があるか、未知のフィールドが無視されるか、新しいenum値が安全か、変換がリバーシブルかを記録します。古いコンシューマーが未知のフィールドを拒否する場合は、本番トラフィックを直接拡大してはいけません。

5. サンプル、リプレイ、シャドウトラフィックによる検証

すべてのFacetに対して最小限、完全、無効なサンプルを保持します。新しいパーサーを通じて過去のイベントをリプレイし、構造化された出力とクエリインデックスを比較します。次に、本番のリネージグラフを変更することなく、新しいプロデューサーからのイベントをシャドウトピックにコピーします。パース失敗、未知のFacet、バージョン分布、エンドツーエンドのレイテンシを監視し、異常があればカナリアを停止します。

6. 非推奨化とロールバックの設計

旧バージョンの終了期限、移行担当者、コンシューマーリストを公開します。プロデューサーはまずデュアルライトを行い、コンシューマーのアップグレード後に古いフィールドを停止できます。ロールバックでは、古いスキーマ、クライアント、リプレイ機能を保持する必要があります。古いバージョンのイベントを削除すると、コードは復元できてもデータを解釈する能力は復元できません。

質の高い回答例

この架空の回答は、実際のイベントタイプや組織の制約に合わせて置き換える必要があります:

私ならRunEvent、JobEvent、DatasetEventのプロデューサー、コンシューマー、クライアントバージョン、リプレイジョブを棚卸しし、変更がコアスキーマにあるのかカスタムFacetにあるのかを特定します。後方互換性のあるオプションフィールドを優先し、意味が変わる場合はプロジェクト固有のプレフィックスを付けたフィールドまたはFacetを追加します。JSON Schemaのバージョンを引き上げ、JavaおよびPythonクライアントを生成し、最小限、完全、無効なサンプルを更新します。検証では、新しいプロデューサーと古いコンシューマー、古いプロデューサーと新しいコンシューマー、過去のリプレイをカバーし、続いてシャドウトラフィックによるカナリアリリースを行います。パース失敗、未知のFacet、バージョン分布、レイテンシを監視します。コンシューマーが移行基準を満たした後、文書化された非推奨期間中にデュアルライトを終了します。ロールバックによってイベントの意味が失われないよう、古いスキーマ、クライアント、リプレイパスは引き続き利用可能な状態に保ちます。

よくある間違い

フィールドの追加は常に互換性があると考えること

オプショナル性、未知のフィールドへの挙動、自動生成クライアントの更新によって結果が変わります。互換性マトリックスと具体的なフィクスチャを提示してください。

バージョンを上げずにスキーマを変更すること

バージョンURLによってコンシューマーはセマンティクスを識別できます。バージョンアップを怠ると、コード生成が壊れたり、異なるコンシューマーが古い定義を想定してしまったりする可能性があります。

カスタムFacetを任意のJSONとして扱うこと

カスタムFacetには一意のプレフィックスと不変のバージョニングされたスキーマURLが必要です。名前の衝突により、エンティティの以前のFacetインスタンスが暗黙的に置き換えられてしまう可能性があります。

リプレイを行わず、新しいイベントのみをテストすること

リネージシステムは履歴をリプレイすることがよくあります。リプレイテストを行わないと、フィールドの欠落、混在バージョン、インデックスの移行問題が隠れたままになります。

フォローアップと発展的な演習

古いコンシューマーが未知のFacetで失敗します。どのようにリリースしますか?

まず、コンシューマーが未知のFacetを無視するようにするか、新しいFacetをシャドウトラフィックにルーティングします。パーサーとメトリクスの挙動が安全になった後にのみプロデューサーをカナリアリリースします。すべてのJSONコンシューマーが寛容であると決して想定しないでください。

コアフィールドではなく新しいFacetを使用するのはどのような場合ですか?

独立して進化できるコンテキストにはFacetを使用します。情報がJob、Run、Datasetのアイデンティティやライフサイクルを変更する場合にのみ、コアスキーマの変更を検討してください。フィールド数よりも、クエリと所有権の境界がなぜ重要であるかを説明します。

Javaの生成は成功したが、Pythonが失敗しました。どうしますか?

リリースを一時停止し、ジェネレーターがオプションフィールド、enum、未知のプロパティをどのように処理しているかを比較し、スキーマまたはテンプレートを修正して両方のクライアントスイートを実行します。1つの言語が成功しただけでは、移行の完了基準にはなりません。

移行期間を過ぎても古いプロデューサーが残っています。どのように対応しますか?

残りのソースをプロデューサーおよびチームごとにリストアップし、旧バージョンの書き込みを制限し、明示的なエラーまたは縮退パスを提供します。ハードストップによって重要なリネージが失われる場合は、リスクを記録した上で期間を延長します。古いイベントやスキーマを削除してはなりません。

公開情報ソース

関連する質問