プロンプトと適用されるコンテキスト
あなたの会社には、Airflow、Spark、dbt、Kafkaにまたがる30,000のデータセットと1日あたり200,000件のパイプライン実行があります。チームは次の3つの質問に答える必要があります:データセットやフィールドの出所はどこか、提案された変更によって何が影響を受けるか、そして特定の実行によってどの出力が生成されたか。テーブルおよびカラムレベルの依存関係をキャプチャし、アップストリームおよびダウンストリームの探索をサポートし、過去の特定時点のリネージを再構築し、リトライや失敗・部分実行を処理し、メタデータアクセスを強制し、グラフが信頼するに足る完全性を備えているかを公開するリネージシステムを設計してください。
面接では、イベント取り込みのピークを毎秒500イベント、3ホップの探索は通常2秒以内に完了し、詳細な実行履歴は1年間保持されると想定します。これらはシナリオの入力条件であり、業界のベンチマークではありません。設計では、実際のトラフィックを観測した後にこれらの制限をどのように測定し、改定するかを説明する必要があります。
現在の2026年のデータエンジニアリングの面接資料では、データリネージの設計方法を候補者に直接問い、テーブル、カラム、ジョブレベル、メタデータキャプチャ、命名規則、および変更の影響を挙げています。OpenLineage 1.50.0は有用な事実ベースラインを提供します:Job、Run、Datasetがコアエンティティであり、ネームスペースと名前がJobとDatasetを識別し、RunはUUIDを使用し、Runイベントには定義されたライフサイクル状態があり、ファセットがスキーマとカラムの依存関係でモデルを拡張します。中心となる能力がメタデータモデリング、パイプラインセマンティクス、影響分析、およびデータガバナンスであるため、このカテゴリはdataです。
面接官が評価するポイント
最初のシグナルは、候補者がアイデンティティとセマンティクスから始めるかどうかです。同じテーブルがorders、prod.orders、およびウェアハウスURLとして現れたり、リトライが新しいジョブと誤認されたりすると、グラフは使用できなくなります。グラフデータベースを選択する前に、安定したリソースキー、環境境界、ジョブ定義、実行ID、フィールドパス、およびバージョンセマンティクスを確立する必要があります。
2番目のシグナルは、リネージが実行の実態を反映しているかどうかです。ソースコードからの宣言的リネージ(declared lineage)はリリース前の確認に役立ち、実際の実行から得られる観測リネージ(observed lineage)は何が読み書きされたかを証明します。失敗した実行は一時的または部分的な出力を書き込んだ可能性があり、成功した実行ステータスであってもデータの正確性を証明するものではありません。優れた設計は、イベントエビデンス、実行状態、宣言されたエッジ、観測されたエッジ、および公開状態を明確に区別します。
3番目のシグナルはシステム設計の深さです。候補者は、プロデューサーの統合、高耐久でべき等な取り込みパス、不変の生イベント、正規化、時間的グラフのマテリアライゼーション、探索インデックス、鮮度とカバレッジのメトリクス、バックフィル、およびアクセス制御をカバーする必要があります。「グラフデータベースに入れる」と言うだけでは、最も困難な問題をスキップすることになります。
最後に、面接官は適切に調整された信頼性を求めます。計装(instrumentation)の欠落は可視化されたままでなければなりません。重要なジョブの60%から組み立てられたきれいなグラフは、UIでそれが完全であるかのように提示されると危険です。強力な回答は、プロベナンス(来歴)、観測時刻、信頼度、カバレッジ、およびギャップを公開し、ユーザーが影響クエリがデプロイの判断に十分であるかどうかを判断できるようにします。
回答前に明確にすべき質問
- リネージはどのような決定をサポートする必要があるか? インシデント診断、デプロイ前の影響分析、ガバナンスの検出、PIIの伝播、および監査エビデンスでは、鮮度、履歴、正確性の要件が異なります。
- 何がデータセットとしてカウントされるか? テーブル、ビュー、ファイル、オブジェクトプレフィックス、Kafkaトピック、マテリアライズドビュー、ダッシュボード、機械学習の特徴量には、明示的な粒度が必要です。すべてのファイルをノードとして扱うと、使用不可能なグラフが作成される可能性があります。
- 宣言的リネージ、観測リネージ、またはその両方が必要か? 宣言的リネージは実行前に将来の変更を示すことができます。観測リネージは入力と出力を具体的なRunに関連付けることができます。UIはそれらの意味を暗黙的に統合してはなりません。
- 必要なフィールドレベルの精度はどれくらいか? 直接的な値の導出は、結合(join)、フィルター、グループ化、ソート、ウィンドウ、または条件による間接的な影響とは異なります。論理プランを公開するエンジンもあれば、テーブルリネージのみを公開するエンジンもあります。
- 環境間でデータセットとジョブはどのように識別されるか? ネームスペース、正規名、エイリアス、大文字小文字のルール、リネーム、および所有権を定義します。表示ラベルは耐久性のある主キーではありません。
- 失敗または部分的な実行の後はどうなるべきか? 部分的に書き込まれた出力が公開されるか、隔離されるか、ロールバックされるか、また影響分析にそれらをエビデンス、現在の真実、またはその両方として含めるべきかを明確にします。
- 特定時点の履歴はどのくらいの期間クエリ可能である必要があるか? 1年間の実行イベントがあっても、低レイテンシのサービングレイヤーで展開されたすべてのカラムエッジを1年間保持する必要があるとは限りません。
- どのメタデータが機密か? SQLテキスト、フィールド名、所有権、PIIタグ、およびデータセットの存在自体が、保護された情報を明らかにする可能性があります。探索結果には、カタログと同じ認可規律が必要です。
- スケールとサービス目標は何か? イベントレート、グラフサイズ、探索深度、レイテンシパーセンタイル、目標復旧時点(RPO)、および実行からリネージが可視化されるまでの許容遅延を確認します。
30秒の回答フレームワーク
「正規化されたJob、Run、Dataset、Fieldのアイデンティティをモデル化し、宣言的リネージと観測リネージ、およびテーブルリネージとカラムリネージを分離します。プロデューサーは、耐久性のあるログに支えられた認証済みのべき等なゲートウェイを通じてバージョニングされたイベントを発行します。コンシューマーは生の証拠を保持し、時間的なアップストリームおよびダウンストリームのインデックスを構築します。失敗した出力は、公開が確認されるまで診断用のままになります。探索は深さ、時間、権限によって制限され、プロベナンスとギャップを公開します。遅延、期待されるジョブのカバレッジ、終端イベントの完全性、未解決のアイデンティティ、古いエッジ、サンプリングされたパスの正確性を測定し、信頼性の高いカラム抽出を追加する前に、重要なパイプラインのテーブルリネージからローンチします。」
ステップバイステップの詳細な回答
ステップ1:ストレージエンジンの前に真実のモデルを定義する。
4種類のレコードを使用します:
| レコード | 安定したアイデンティティ | 目的 |
|---|---|---|
| Dataset | (namespace, name)と環境 | テーブル、トピック、ビュー、または意図的に選択された論理データセット |
| Field | Datasetのアイデンティティと正規フィールドパス | データセットのスキーマバージョン内のカラムまたはネストされたフィールド |
| Job | (namespace, name)と定義バージョン | 定期的な変換、タスク、クエリ、またはモデル |
| Run | クライアント生成のUUID | Jobの1回の実行。リトライは別個の実行である場合にのみ含む |
ネームスペースは、Datasetの場合はデータソースから、Jobの場合はスケジューラまたは処理システムから取得する必要があります。エイリアスは有効期間とともに個別のマッピングに保持します。analytics.ordersからanalytics.sales_ordersへの名前変更は、文字列の類似性に基づいて暗黙的にアイデンティティを作成または統合してはならず、明示的な名前変更またはエイリアスイベントが必要です。
コンパイルされたSQL、dbtマニフェスト、または構成からの宣言的リネージを、Runによって発行された観測リネージとは別にモデル化します。テーブルエッジをフィールドエッジとは別にモデル化します。フィールドエッジには、出力フィールド、入力フィールド、変換の種類、および依存関係が直接的な値の導出であるか間接的な影響であるかを記録します。OpenLineageのカラムモデルは、直接的なアイデンティティ、変換、集計を、間接的な結合、グループ、フィルター、ソート、ウィンドウ、条件の影響と区別します。この区別は、フィールドの値、型、または可用性の変更が出力に影響を与えるかどうかを判断する際に重要です。
すべてのエッジには、validFrom、オプションのvalidTo、observedAt、プロデューサー、ソースイベント、Jobバージョン、Run ID、実行ステータス、リネージの種類、および信頼度または導出方法を含める必要があります。これらの属性により、修飾されていない矢印が「いつの時点で?」「何に基づいて?」に答えることができるエビデンスに変わります。
ステップ2:実行にできるだけ近い場所でリネージをキャプチャする。
既存のネイティブまたはメンテナンスされている統合を使用します:タスクライフサイクルのためのオーケストレーションリスナー、Spark論理プランの計装、dbtアーティファクトと実行結果、ウェアハウスおよびストリーミングシステムのコネクタまたはクエリ履歴。SQLに対する正規表現よりも、解析された論理プランまたはエンジンが生成した論理プランを優先します。動的SQL、マクロ、ストアドプロシージャ、一時オブジェクト、ユーザー定義関数、および実行時分岐の選択により、文字列の解析は不完全になります。
リネージペイロードの周りにバージョニングされた取り込みエンベロープを定義します:
{
"eventId": "producer-unique-id",
"producer": "spark-prod-eu",
"schemaVersion": "1.0",
"emittedAt": "2026-07-19T00:00:00Z",
"job": { "namespace": "spark-prod", "name": "daily_orders" },
"runId": "53ee3770-86fa-4cb9-8c31-a09072dd88f7",
"state": "COMPLETE",
"inputs": [{ "namespace": "warehouse-prod", "name": "raw.orders" }],
"outputs": [{ "namespace": "warehouse-prod", "name": "mart.daily_orders" }]
}eventIdは、べき等性のためのこのプラットフォームエンベロープの要件です。すべての外部リネージ標準で必須のフィールドであると主張しないでください。プロデューサーは同じIDで配信をリトライします。ゲートウェイはプロデューサーを認証し、スキーマの互換性とサイズ制限をチェックし、受信時刻を付加し、確認応答(ACK)を返す前にイベントをパーティション分割された高耐久ログに書き込みます。無効なイベントは、理由、プロデューサー、および安全なペイロード参照とともに隔離ストリームに送信され、ログの中に消えてしまうことはありません。
Run IDによるパーティショニングは、無関係な実行を分散させながら、Runのローカルな順序を保持します。イベント時刻は遅延したりスキューしたりする可能性があるため、コンシューマーは発行時刻と受信時刻の両方を保存し、ライフサイクルルールを適用します。OpenLineageはSTART、RUNNING、COMPLETE、ABORT、FAIL、およびOTHERを定義しています。遅れて到着したSTARTによって終端イベントが取り消されてはなりません。マテリアライズされた現在の状態を変更しなくなった場合でも、不変イベントは保持します。
ステップ3:プロベナンスを損なわずに正規化する。
ノーマライザーは、各統合のペイロードを正規のアイデンティティとエッジセマンティクスに変換します。登録されたエイリアス、大文字小文字の規約、環境、一時データセット、ネストされたフィールドパスを解決します。未知のアイデンティティは推測されるのではなく、未解決キューに入ります。生のイベント、正規化されたレコード、リゾルバーのバージョン、および警告はリンクされたままになるため、誤ったマッピングを修正して再生(リプレイ)できます。
スキーマの変更により、バージョニングされたフィールド定義が作成されます。customer_idを削除して後で再作成しても、フィールド履歴が連続していることを意味しません。スキーマハッシュまたはカタログバージョンと有効期間により、特定時点のクエリで適切なフィールドを選択できます。ストリーミングパイプラインの場合、トピックと変換Jobを安定した粒度で記録します。すべてのパーティションとオフセットのペアを永続的なグラフノードに爆発させるのではなく、パーティションとオフセットをRunのエビデンスとして保持します。
実行状態は慎重に扱ってください。COMPLETEはJobの実行が完了したことを意味し、出力のビジネス品質を保証するものではありません。FAILまたはABORTイベントは、依然として入力と試行された出力を報告する可能性があります。診断のためにこれらの観測されたエッジを保存しますが、出力公開ポリシーが満たされた場合にのみ、現在の公開されたリネージをマテリアライズします。そのポリシーには、アトミックなコミットマーカーまたは個別の品質ゲートが必要な場合があります。明示的にラベルを付けます。
ステップ4:目的に合ったインデックスを使用してイベントソーシングされた時間的グラフを構築する。
耐久性のあるログと不変のオブジェクトストレージアーカイブがリカバリソースとなります。コンシューマーは次の3つのプロジェクションを作成します:
- 正規のJob、Dataset、Field、スキーマ、エイリアス、オーナー、アクセス制御ポリシー用のメタデータストア。
- 有効期間と実行プロベナンスを持つ宣言的および観測リネージ用の時間的エッジストア。
- ライフサイクルイベント、入力/出力のスナップショット、ステータス、診断の詳細用のRunストア。
再現可能な第1パスのキャパシティ見積もりにより、1日のRun数とイベントスループットの混同を防ぎます。最低限、200,000の各Runに対して1つのSTARTと1つの終端イベントがあると、1日あたり400,000イベント、平均で毎秒約4.6イベントが生成されます。典型的なRunが1つのSTART、2つのRUNNING更新、および1つの終端イベントを発行する場合、1日あたり800,000件、毎秒約9.3件になります。したがって、毎秒500件という入力はバースト時の目標であり、平均値ではありません。生のペイロードの平均サイズを20 KBと仮定すると、800,000イベントには、圧縮とレプリケーションの前に1日あたり約16 GB、年間5.8 TBが必要です。カラムファセットによってこの見積もりが大幅に変わる可能性があるため、ペイロードサイズとRunあたりのイベント数を測定する必要があります。
低レイテンシの影響クエリのために、正規ノードIDと時間バケットまたはアクティブバージョンをキーとするダウンストリームおよびアップストリームの両方の隣接インデックスを維持します。幅優先探索(BFS)には、明示的な最大深度、ノード数、エッジタイプ、環境、時間境界があります。制限に達した場合、サービスは部分的な結果を示すインジケーターを返します。グラフデータベースでこれを実装できますが、必須ではありません。この規模では、適切なインデックスを持つリレーショナルエッジテーブルまたはKey-Valueの隣接サービスの方がシンプルな場合があります。選択する前に、実際のファンアウトと特定時点の述語をベンチマークしてください。
カラムリネージはテーブルリネージよりもはるかに大きくなる可能性があります。テーブルエッジをホットなプロジェクションに保存し、頻繁にクエリされるフィールドの隣接関係をホットに保ち、古いまたは使用頻度の低い詳細なエッジを圧縮された履歴ストアに配置します。完全な推移的閉包(transitive closure)を事前計算しないでください。高密度のグラフでは、更新と認可のコストが高くなります。ノード、方向、深さ、時間、エッジタイプのフィルター、および認可スコープによって制限付きクエリ結果をキャッシュします。関連するエッジバージョンが変更されたときにそれらを無効化します。
ステップ5:クエリコントラクトを明示的にする。
APIは以下をサポートする必要があります:
- 深さと特定時点によって制限された、DatasetまたはFieldのアップストリームまたはダウンストリームの探索。
- 提案されたスキーマまたはフィールドの変更に対する影響分析(直接的および間接的な依存関係を区別)。
- 正確な入力、出力、Jobバージョン、ライフサイクル、および公開状態を示すRunのルックアップ。
- 宣言的と観測の区別、最終観測時刻を含む、返されたすべてのエッジのプロベナンス。
- 計装されていないJob、未解決のアイデンティティ、古いプロデューサー、および切り捨てられた探索のためのギャップマーカー。
認可は探索の後にのみ適用することはできません。非表示のDatasetの名前や存在自体が機密情報である可能性があります。展開中に呼び出し元のポリシーを解決し、ガバナンスルールに従って保護されたノードを省略または置換し、次数カウントから非表示の隣接ノードが漏洩するのを防ぎ、機密性の高い探索を監査します。キャッシュキーには認可スコープが含まれているため、あるユーザーのグラフが別のユーザーに提供されることはありません。
2秒以内の3ホップという目標について、方向、深さ、ファンアウト、時間フィルター、カラムクエリとテーブルクエリごとにP50、P95、P99を測定します。制限されたノードバジェットを超えた場合、レスポンスは継続トークンまたは明示的な切り捨てを返すことができます。不完全なグラフを黙って返すことは受け入れられません。
ステップ6:再生(リプレイ)、バックフィル、ディザスタリカバリを設計する。
コンシューマーは耐久性ログのオフセットをチェックポイントします。処理は少なくとも1回(at-least-once)行われるため、プロジェクションの書き込みではべき等性のためにeventIdとプロジェクションバージョンを使用します。正規化のバグは、新しいリゾルバーバージョンをデプロイし、生イベントからシャドウプロジェクションにリビルドし、カウントとサンプリングされたパスを比較し、検証後にリーダーを切り替えることで修復されます。完全な再生中に唯一のサービンググラフを上書きしないでください。
暗号化とライフサイクルポリシーを使用して、必要な1年間、不変ストレージに生イベントを保持します。正規メタデータとエッジプロジェクションのスナップショットを作成してリカバリ時間を短縮しますが、スナップショットとそれ以降のイベントで同じ結果が再現されることを証明します。リカバリ目標を定義し、取り込みリージョンの喪失をテストし、プロデューサーのリトライによって余分なエッジが作成されないことを確認します。
特定時点のリネージは、現在のグラフにタイムスタンプラベルを付けたものではなく、エッジの有効性と観測時刻を使用します。先月のクエリは、その時点で有効だったアイデンティティ、スキーマバージョン、認可されたエッジを解決する必要があります。ソースが履歴を発行したことがない場合は、履歴を捏造するのではなく、その制限を返します。
ステップ7:信頼性を製品の特性として測定する。
少なくとも以下のメトリクスを追跡します:
| シグナル | 明らかになること |
|---|---|
| プロデューサーごとの取り込み遅延と拒否されたイベント率 | グラフが最新であり、コントラクトが依然として一致しているかどうか |
| 期待されるジョブの発行カバレッジ | リネージイベントを生成しなかったスケジュールされたJob |
| 終端イベントの完全性 | STARTはあるが終端状態がないRun |
| アイデンティティ解決の失敗率 | 未知または競合する名前に孤立したエッジ |
| 観測されたエッジの鮮度 | 最近の正常な公開によって確認されていないリネージ |
| 重要度ティア別のテーブル/カラムカバレッジ | 重要なアセットに必要な深さがあるかどうか |
| サンプリングされたパスの正確性 | 既知の入出力フィクスチャと実際の実行が期待通りのパスを生成するかどうか |
| 探索の切り捨てとレイテンシ | サービング目標が高ファンアウトの障害を隠していないかどうか |
カバレッジには分母が必要です。受信したイベント数だけでなく、リネージを発行するRunをスケジューラインベントリまたはウェアハウスのクエリ履歴と比較します。「12分前に観測」、「宣言のみ」、「カラムリネージ利用不可」、「17個のアップストリームJobのうち2個が未計装」などの信頼バッジを公開します。障害モードを隠すような不透明な単一の信頼度スコアは避けてください。
アイデンティティ、集計、結合、フィルター、リネーム、リトライ、障害、部分公開のケースを含む決定論的なパイプラインフィクスチャで検証します。本番環境では、最近の実行をサンプリングし、エンジン計画、発行されたイベント、正規化されたエッジ、およびクエリ結果をエンドツーエンドで比較します。すべてのプロジェクションリリース時にノード数とエッジ数を照合します。
ステップ8:意思決定の価値に応じて段階的に展開する。
ビジネス上重要なドメインとテーブルレベルのリネージから始めます。正規のアイデンティティとオーナーを登録し、最も影響の大きいスケジューラとエンジンを計装し、包括的な影響分析を約束する前に鮮度とカバレッジを公開します。次に、信頼性の高い論理プランを持つエンジンのカラムリネージ、デプロイ前の宣言的リネージ、履歴、およびPIIの伝播を追加します。
成功は意思決定によって測定されます:使用可能なデプロイ前の影響レポートを含む重要な変更の割合、最初の不良なアップストリーム境界を特定できるインシデントの割合、未解決のアイデンティティの削減、重要なプロデューサーのカバレッジなどです。ノードの数や視覚的に密度の高いグラフは成功の指標ではありません。
質の高い模範解答
「私は意思決定とアイデンティティを定義することから始めます。このシステムでは、DatasetまたはJobは環境内の正規のネームスペースと名前によって識別され、Fieldは正規のパスとスキーマバージョンを追加し、RunはUUIDによって識別される1回の実行です。エイリアスとリネームは、明示的で時間制限のあるマッピングです。コンパイルされた計画からの宣言的リネージを実行からの観測リネージと分離し、テーブルの依存関係をフィールドの依存関係と分離して保持します。
収集時には、Airflow、Spark、dbt、および関連するKafka処理フレームワークの保守された統合がバージョニングされたペイロードを発行します。正規表現では動的SQL、結合、マクロ、または実行時分岐を確実に理解できないため、SparkおよびSQLエンジンは可能な限り論理プランを使用する必要があります。各プラットフォームエンベロープには、プロデューサー固有のイベントID、プロデューサー、スキーマバージョン、Jobアイデンティティ、Run ID、ライフサイクル状態、および入力と出力が含まれます。取り込みゲートウェイはプロデューサーを認証し、ペイロードを検証し、確認応答を返す前に耐久性のあるログに追加します。同じイベントIDの重複配信はべき等です。無効なイベントは可視化された隔離キューに送られます。
生イベントは不変です。ノーマライザーは登録されたエイリアスを解決し、ソースイベントとリゾルバーバージョンを保持しながら、バージョニングされたJob、Dataset、Field、およびエッジを作成します。未知のアイデンティティを推測することはありません。Runの状態はサービングに影響を与えます:STARTとRUNNINGはエビデンスを追加できますが、COMPLETE、ABORT、FAILは終端です。失敗したRunは診断のために引き続き利用可能ですが、データが可視化されたことを示す独立した公開マーカーがない限り、その試行された出力は現在の公開されたリネージとして昇格されません。COMPLETEは実行の完了を証明するものであり、データの正確性を証明するものではありません。
コンシューマーは、正規メタデータストア、時間的エッジストア、およびRunストアを構築します。アップストリームとダウンストリームの両方の隣接インデックスが、制限付き幅優先探索をサポートします。すべてのエッジには、有効期間、観測時刻、プロデューサー、Jobバージョン、Run、ステータス、宣言的か観測かの種類、および直接的か間接的かのフィールド変換情報が付与されます。特定時点のクエリは、その時点で有効なアイデンティティとエッジを選択します。高いファンアウト、バージョンの変更、認可によって高コストでリスクが高くなるため、ユニバーサルな推移的閉包を事前計算することはありません。
30,000のデータセットと1日あたり200,000のRunに対して、ピーク時毎秒500イベントは、耐久性のあるパーティション化されたログとインデックス付きのリレーショナルまたはKey-Valueプロジェクションから開始するのに十分控えめな規模です。その後、実際のファンアウトに対してグラフ専用ストレージをベンチマークします。カラムエッジはより大きなディメンションであるため、最近および頻繁にクエリされる隣接関係はホットな状態を維持し、詳細な古い履歴は圧縮できます。3ホップ・2秒という目標は、グラフタイプとファンアウトごとにP50、P95、P99で測定されます。すべてのリクエストには深さとノードのバジェットがあり、明示的な継続マーカーまたは切り捨てマーカーを返します。
クエリサービスは、グラフ展開中に認可を実行します。非表示のノード名、存在、または隣接ノード数を漏洩してはならず、そのキャッシュキーには呼び出し元のポリシーのスコープが含まれます。レスポンスにはプロベナンスと可視化されたギャップ(宣言のみ、観測時刻、未解決のアイデンティティ、古いプロデューサー、欠落しているカラムリネージ、計装されていないJob)が含まれます。
プロジェクションをリプレイ可能にします。生イベントは1年間保持されます。コンシューマーはオフセットをチェックポイントし、べき等に書き込みます。リゾルバーやスキーマのバグは、シャドウプロジェクションを再構築し、アクティブなプロジェクションと照合し、既知のパスをテストし、検証後にのみ切り替えることで修正されます。スナップショットによってリカバリが短縮されますが、決定論的な再構築を証明するために後続のイベントでテストされます。
最後に、期待されるジョブのカバレッジ、終端イベントの完全性、アイデンティティ解決の失敗、エッジの鮮度、重要なテーブルとカラムのカバレッジ、拒否されたイベント、サンプリングされたパスの正確性によって信頼性を測定します。分母はスケジューラインベントリとクエリ履歴から取得します。重要な財務および顧客ドメインのテーブルリネージをローンチし、カバレッジギャップを公開してから、抽出が信頼できるカラムおよび宣言的リネージを追加します。システムが成功したと言えるのは、単にグラフに多くのノードが含まれているときではなく、エンジニアがエビデンスに基づいてより安全に変更を行い、インシデントを追跡できるようになったときです。」
よくある間違い
- グラフデータベースから始める → ストレージの選択は、アイデンティティ、実行状態、履歴、または計装の欠落を解決しない → まずエンティティ、エビデンス、ライフサイクル、クエリコントラクトを定義する。
- 表示名を主キーとして使用する → エイリアス、大文字小文字の変更、環境、リネームによってノードが分割または統合される → 正規のネームスペース/名前のアイデンティティと明示的な時間制限付きエイリアスを使用する。
- 宣言的リネージと観測リネージを同一として扱う → コンパイルされた可能性は実行時のパスと異なる場合がある → すべてのエッジの種類とプロベナンスを保存し、クエリでフィルターできるようにする。
- 失敗したRunからのすべての試行された出力を昇格させる → 部分的なファイルやテーブルが誤った現在の真実になる → 診断エビデンスは保持するが、エッジをアクティブにする前に公開セマンティクスを要求する。
- COMPLETEが正しいデータを意味すると想定する → 重複または無効な出力で実行が終了する可能性がある → データ品質状態を実行ライフサイクルから分離して維持する。
- すべてのSQLを正規表現で解析する → 動的SQL、方言、マクロ、ネストされた式によって誤った依存関係が生成される → エンジン計画とサポートされているパーサーを優先し、サポートされていないカバレッジを公開する。
- イベントコントラクトなしでペイロードハッシュによって重複排除する → 個別の進行状況イベントがコンテンツを共有し、リトライでタイムスタンプが異なる場合がある → 取り込みエンベロープにプロデューサー側で安定したイベントIDを要求する。
- 現在のグラフのみを保持する → 過去の影響やインシデントの再構築が不可能になる → 不変イベントと時間的エッジバージョンを保持する。
- すべての推移的パスを事前計算する → ファンアウト、バージョンの変更、認可によって高コストな無効化が発生する → 制限付き探索とターゲットを絞ったキャッシュを使用する。
- 最終レスポンスでのみ認可する → 探索中またはキャッシュ中に非表示のノードや次数カウントが漏洩する可能性がある → 展開中にポリシーを適用し、キャッシュキーのスコープを設定する。
- 受信イベント数をカバレッジとして報告する → サイレントなプロデューサーはイベントとメトリクスの両方から消える → スケジューラインベントリまたはクエリ履歴と比較する。
- 未知のギャップがあるのに完全に見えるグラフを表示する → ユーザーが危険な変更決定を下す → 関連するすべての結果で鮮度、プロベナンス、未解決のアイデンティティ、欠落しているプロデューサーを提示する。
フォローアップの質問と回答
フォローアップ1:失敗したSpark RunがFAILを発行する前にテーブルパーティションを書き込みました。エッジは表示されるべきですか?
そのRunと試行された入出力エッジを、FAILのタグが付けられ未公開の、観測された診断エビデンスとして保持します。現在の本番グラフに表示されるかどうかは、ストレージのコミットと公開ポリシーによって異なります。パーティションが可視化された場合は、ロールバックまたは検証が行われるまで、失敗したバージョンまたは疑わしいバージョンとして表示します。書き込みがアトミックで中止された場合は、アクティブにしないでください。実行エビデンスと公開状態の両方を保持することで、フォレンジックの詳細を失ったり、部分的な出力を信頼できる真実として提示したりすることを回避できます。
フォローアップ2:リネージの送信をサイレントに停止したプロデューサーをどのように検出しますか?
受信イベントのメトリクスだけでは、不在のプロデューサーを検出できません。Airflowのスケジュール、Sparkの履歴、dbtの実行結果、ウェアハウスのクエリログ、または別の独立したコントロールプレーンから、期待されるRunのインベントリを構築します。遅延ウィンドウ内で、正規のJobおよびRunアイデンティティによって期待されるRunをリネージイベントに結合します。開始の欠落、終端イベントの欠落、重要度ティア別のカバレッジ低下についてアラートを発し、無効化されたJobと破損した統合を区別します。
フォローアップ3:変更されたJobが実行される前に影響分析にどのように回答しますか?
提案されたコンパイル済みプランまたはマニフェストから抽出された宣言的リネージを使用し、アクティブな定義と比較します。削除または変更された出力からダウンストリームを探索し、結果にデプロイ前の宣言的エビデンスとしてラベルを付け、観測リネージがそれと一致するか不一致かを示します。CIゲートは、影響を受ける重要なアセットに対してオーナーのレビューを要求できます。将来の実行時パスが観測されたと主張しないでください。デプロイ後も動的分岐が異なる場合があります。
フォローアップ4:なぜすべてを1つのグラフデータベースに保存しないのですか?
ベンチマーク後は単一のデータベースでも許容できる場合がありますが、Runイベント履歴、不変の再生、メタデータ検索、低レイテンシの隣接関係ではアクセスパターンが異なります。耐久性のあるイベントソースを再構築可能なプロジェクションから分離することで、リカバリが保護され、各プロジェクションが個別に進化できるようになります。これらのパターンを満たす最小限のストアから開始し、ファンアウトと時間的クエリのコストを測定し、エビデンスが運用コストを正当化する場合にのみ専用ストレージを追加します。
フォローアップ5:カラムリネージはエッジ数を数百倍に増やします。最初に何を縮小(デグレード)しますか?
正確性と重要な意思決定を保護します。テーブルリネージと重要度の高いドメインの最近のカラムリネージをホットに保ち、古い詳細なエッジを圧縮履歴に移動し、使用頻度の低いフィールドパスを非同期で計算します。探索バジェットを強制し、明示的な部分ステータスを返します。カラムの回答をテーブルの推測で暗黙的に置き換えないでください。デグレードが測定可能かつ可逆的であり続けるように、エンジンとドメインごとにカラムのカバレッジを追跡します。