代表的な面接トピック

データエンジニアリング面接:強制力のあるデータコントラクトをどのように設計しますか?

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

質問

複数のチームが同じイベントやデータセットに依存していますが、プロデューサー側がフィールド、意味、更新時刻を頻繁に変更してしまいます。データコントラクトをどのように設計し、それがコンシューマーを保護することをどのように証明しますか?

プロンプトとスコープ

この質問は、データエンジニアがチーム間のデータ合意を、検証可能で進化可能なインターフェースへと変換できるかどうかをテストするものです。決済チームが注文イベントを発行し、それが財務ダッシュボード、リスク特徴量、および運用レポートで使用されていると仮定します。フィールドの型、ビジネス上の意味、品質しきい値、および利用可能期間(アベイラビリティウィンドウ)が合意されていないため、小さな変更が下流のインシデントに発展する可能性があります。

これはデータエンジニア、データプラットフォームエンジニア、データプロダクトガバナンスの役割に適しています。特定のKafka、データウェアハウス、またはベンダーの選択ではなく、コントラクトの境界、オーナーシップ、バージョンの互換性、検証、および障害処理に焦点を当ててください。プロデューサーが何を保証し、コンシューマーが何を前提としてよいか、また保証が満たされない場合にどのようにブロックまたはデグレードさせるかを述べてください。

面接官が評価している点

優れた回答は、データコントラクトを単なるスキーマと区別します。コントラクトには、フィールドのセマンティクス、品質アサーション、機密データ、サービスレベル、オーナーシップ、変更ルールも記述されます。コンシューマーのニーズから最小限のコントラクトを導き出し、リリース前チェックとランタイム監視の境界を説明し、追加、非推奨化、セマンティックな変更のための互換性ポリシーを使用します。また、コントラクト違反が発生した際の通知先オーナー、隔離境界、ロールバックパス、およびリプレイ戦略を指定します。

行うべき明確化のための質問

  • そのアセットはイベントストリーム、テーブル、ファイル、またはモデルの特徴量のいずれですか? どの程度の鮮度とレイテンシが許容されますか?
  • どのコンシューマーがそれに依存しており、どのフィールド、時間セマンティクス、精度、保持期間を必要としていますか?
  • ここでの「正確さ」とは何を意味しますか:必須性、一意性、範囲、列挙型、フィールド間ルール、照合などですか?
  • どのフィールドに個人データまたは財務データが含まれており、アクセス、マスキング、および許可された使用を誰が承認しますか?
  • その変更は後方互換性がありますか、デュアルライトが必要ですか、それともリリースゲートで拒否する必要がありますか? 違反を遅延、隔離、またはロールバックすることはできますか?

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

「まずコンシューマーにビジネスニーズを提示してもらい、コントラクトを構造、セマンティクス、品質、鮮度、セキュリティ、および責任に分割します。各コントラクトにはオーナー、バージョン、ステータス、および変更ポリシーを持たせます。プロデューサーはリリース前にスキーマと品質のチェックを実行し、コンシューマーは取り込み時に鮮度と可用性を監視します。互換性のある変更は直接リリースし、破壊的変更には新しいバージョン、デュアルトラック移行、および非推奨期間を使用します。チェックに失敗した場合は不良データを隔離し、オーナーに通知し、リプレイ可能な未加工の入力を保持します。この設計を、変更障害率、違反が最初に検出された場所、および復旧時間によって検証します。」

ステップ・バイ・ステップの回答

ステップ 1: コンシューマーのユースケースからコントラクトの境界を定める

プロデューサーのテーブルからすべてのカラムをコピーするのではなく、コンシューマーが実際に必要とするフィールドと意思決定をリストアップします。各フィールドについて、ビジネス上の意味、単位、タイムゾーン、NULL許容性、およびソースを記録します。例えば、total_amount がセントなのかドルなのか、created_at がイベント発生時刻なのか書き込み時刻なのかなどです。内部実装の詳細は共有プロミス(約束事)の外部に置いておきます。

ステップ 2: 構造、セマンティクス、および品質アサーションを定義する

構造は、フィールド名、型、必須性、およびネストをカバーします。セマンティクスは、列挙型、単位、時間枠、および計算定義をカバーします。品質アサーションは、NULL、一意性、範囲、分布、およびフィールド間関係をカバーします。OpenMetadata はスキーマ、セマンティクス、セキュリティ、ビジネスアサーション、SLA、およびステータスを分離しています。このような階層化により、「フィールドが存在する」ことを「データが信頼できる」と誤認するのを防ぎます。

ステップ 3: 鮮度、セキュリティ、およびオーナーシップを明確にする

リフレッシュ頻度、最大レイテンシ、保持期間、および利用可能期間を定義します。プロデューサー側のオーナー、バックアップ担当者、およびコンシューマーサポートチャネルを指定します。機密フィールドには分類ラベル、アクセスポリシー、および許可された使用に関する制約を追加します。境界は強制可能でなければなりません。プロデューサーはコントラクトへの準拠を保証し、コンシューマーは独自のビジネス派生ロジックを引き続き検証します。

ステップ 4: バージョニングと互換性ルールを選択する

コントラクトのバージョンとデータプロダクトの実装バージョンを分離します。オプションフィールドの追加は通常互換性がありますが、フィールドの削除、型の変更、列挙型の縮小、または時間セマンティクスの変更は高リスクです。破壊的変更の場合は新しいバージョンまたは変換レイヤーを公開し、コンシューマーが移行する間デュアルライトを行い、期限を設定し、使用量と非推奨期間がゼロになってから古いバージョンを廃止します。スキーマレジストリの互換性モードだけでは、セマンティックな変更を隠すことはできません。

ステップ 5: コントラクトをリリースゲートに組み込む

コントラクトをバージョン管理システムに保存し、プルリクエストでレビューします。CIはコントラクトの形式を検証し、公開前にサンプルまたはシャドウデータに対して構造、品質、互換性のチェックを実行する必要があります。Confluent のデータコントラクトは、整合性制約、メタデータ、移行ルール、および機密データタグを表現できます。これは、実行可能なルールがドキュメントによる注意喚起よりも強力である理由を示しています。ゲートで失敗した場合はリリースをブロックするか、不良データを検疫(quarantine)にルーティングします。

ステップ 6: ランタイム保護とリカバリを設計する

リリース後は、鮮度、欠損値、列挙型のドリフト、レイテンシ、コンシューマーエラー、およびコントラクトステータスを監視します。リプレイのために、未加工のペイロード、バージョン、および検証結果を保持します。ダッシュボードや特徴量サービスは、ステイル(陳腐化)ラベルを付けた上で直近の信頼できるスナップショットを一時的に使用できます。決済、オーソリ、およびその他の不可逆的なアクションは停止してアラートを出す必要があります。アラートは単に「データの問題」と伝えるだけでなく、オーナーとエスカレーションパスを指し示さなければなりません。

ステップ 7: 1つの変更例で設計を検証する

注文イベントが amount を整数のセントから、金額と通貨を持つオブジェクトに変更すると仮定します。コンシューマーを特定し、新しいバージョンを公開し、デュアルライトを行い、サンプルをリプレイし、新旧の結果を照合してから、古いバージョンを非推奨にします。refunded が「返金開始」から「返金完了」に変更された場合、型が同じであっても破壊的なセマンティック変更となります。この演習は、コントラクトが単なるフィールドの形状だけでなく意味もカバーしていることを証明します。

ステップ 8: コントラクトが機能しているかをレビューする

ゲートによってブロックされた破壊的変更の割合、インシデントが最初に検出された場所、違反から復旧までの時間、古いバージョンに残っているコンシューマー数、およびオーナーのいないデータセットを追跡します。インシデントが依然として下流のダッシュボードで最初に表面化する場合は、チェックのタイミングが遅すぎるかアサーションが弱すぎます。コントラクトに未使用のフィールドが多く含まれている場合は、その境界を狭めます。ビジネス用途やコンシューマーの変化に合わせてコントラクトをバージョン管理および保守します。これは一度きりのドキュメントではありません。

設計のトレードオフと境界

詳細度を高めることでより強力な保護を提供できますが、プロデューサーとコンシューマーの変更コストも増加します。ビジネス上の決定に影響を与えるかリプレイできないチーム間の前提条件は必須のコントラクトに含め、実験的なフィールドはオプションのままにしておきます。ユースケースに応じて品質しきい値を設定します。決済データには厳格な完全性が必要かもしれませんが、探索的分析では明示的な信頼度や鮮度ラベルを付けることで遅延を受け入れることができます。すべてのガバナンスルールを1つのファイルに重複して記述せず、アクセスの承認、保持要件、およびデータプロダクトのドキュメントをリンクさせて、真実のソース(Source of Truth)が並立するのを防ぎます。

どのような場合にリリースを拒否すべきですか?

フィールドの意味が不明瞭な場合、クリティカルなオーナーが存在しない場合、破壊的変更に移行計画がない場合、またはどの境界でも品質アサーションが実行できない場合は、バージョンをアクティブにすることを拒否します。コンシューマーが前提条件を確認し、プロデューサーがサンプルとリプレイの証拠を提供する間は、ドラフト状態のままにしておくことができます。

コンシューマー間の競合をどのように解決しますか?

共有の保証とコンシューマー固有のニーズを分離します。共有コントラクトは小さく、安定しており、検証可能に保ちます。あるコンシューマーがより高い精度やより低いレイテンシを必要とする場合、すべてのコンシューマーに同じコストを強制するのではなく、派生データプロダクトまたは段階的なSLAを提供します。すべての例外には、オーナー、有効期限、および終了条件が必要です。

ロールアウト計画と証拠

影響が大きく、コンシューマーの範囲が限定されているデータセットから始めます。コンシューマーを登録し、最小限のコントラクトを作成し、CIでサンプルチェックを実行してから、本番の境界で鮮度と品質の監視を追加します。最初の移行後、より多くのトピックやテーブルに展開する前に、ブロックされた変更、誤検知、復旧時間、およびコンシューマーのフィードバックをレビューします。この証拠により、ユーザーがいないまま大規模なガバナンスプラットフォームを導入する前にアサーションを調整できます。

パイロット運用の終了基準は何ですか?

終了基準を定義します。複数のリリースサイクルがゲートを通過すること、下流への汚染が発生する前に違反が検出されること、コンシューマーが移行を完了すること、およびオーナーが合意された時間枠内に応答することです。基準が満たされない場合は、失敗したパイロット運用をプラットフォームの成功として見せるのではなく、スコープを狭めるかコントラクトを改訂します。

効果が本物であることをどのように示しますか?

パイロット運用の前後で、破壊的変更の数、最初の検出場所、ロールバック回数、および復旧時間をデータセットとコンシューマーごとにセグメント化して比較します。インシデントが減少すると同時にリリースの頻度も低下している場合は、変更スループットと待ち時間も含めます。ゲートが多くの変更をブロックしているものの誤検知が多い場合は、ゲートを無効にするのではなく、アサーションとサンプルを改善します。

よくある間違いとフォローアップ

フィールド型をデータコントラクトと呼ぶこと

型と必須性は形状を保護するだけであり、通貨、時間セマンティクス、品質、鮮度、アクセス、またはオーナーシップを保護するものではありません。これらの保証がなければ、コンシューマーは構造的には有効であってもセマンティクス的には誤っているデータを受け取る可能性があります。

すべての紛争をコンシューマーに吸収させること

コンシューマーは自身のアウトカムを監視できますが、プロデューサーの共有定義やリリース責任まで引き受けることはできません。コントラクトには、プロデューサーの保証、コンシューマーの前提、および両者間のエスカレーションパスを明記する必要があります。

ランタイムでのみアラートを出すこと

不良データが共有レイヤーに到達した時点ですでに複数の下流システムが汚染されている可能性があります。構造と互換性のチェックを左にシフト(前倒し)します。リリース前に判断できないビジネスアサーションに対してのみ、ランタイム監視と検疫を使用します。

破壊的変更をどのように分類し移行しますか?

スキーマの差分だけでなく、コンシューマーへの影響を判断します。フィールドの削除、型の変更、列挙型の縮小、または単位や時間の定義の変更は、コンシューマーに障害を引き起こす可能性があります。新しいバージョンまたは変換レイヤーを公開し、両方のトラックを検証し、オーナーに通知し、使用量がゼロになり非推奨期間が経過した後にのみ古いバージョンを削除します。

チェックが失敗したがビジネスを継続しなければならない場合、どうしますか?

リバーシブル(可逆的)な表示と不可逆的なアクションを分離します。表示パスでは、ステイルであることを明示するラベルを付けた上で、直近の信頼できるスナップショットを使用できます。決済、オーソリ、およびリスク判定は、不良データを検疫し、影響を受けるアクションを一時停止し、未加工の入力を保持する必要があります。検疫を解除する前に、リプレイ、照合、およびコンシューマーの承認を得ます。

コントラクトが形骸化したドキュメントになるのを防ぐにはどうすればよいですか?

コードレビュー、CIゲート、カタログメタデータ、およびランタイムステータスにコントラクトを組み込みます。すべてのコントラクトをオーナー、バックアップ担当者、コンシューマーリスト、および最終検証時刻にバインドします。違反率、検出場所、復旧時間をレビューし、コンシューマーが存在しない、または強制適用できないエントリは廃止します。

公開情報ソース

関連する質問