プロンプトと適用範囲
このデータエンジニアリング設計の質問では、拒否されたレコードのライフサイクル全体(検知、隔離、修復、再実行、完了)が評価されます。回答では、決定を再現するのに十分な証拠を保持しつつ、正常パスのスループットを保護する必要があります。
面接官が評価しているポイント
- スキーマ、ビジネスルール、重複、遅延、ポイズンピル(poison pill)による障害の識別。
- ペイロードの証拠、ソース位置、理由を含む検疫レコードの設計。
- 再実行における冪等性、バージョン管理されたルール、監査可能な状態の利用。
- バックプレッシャー、アラート、プライバシー、保持期間、オーナーシップの網羅。
確認すべき明確化のための質問
入力がバッチ、ストリーミング、またはその両方であるか、正常なレコードを個別にコミットしてよいか、イベントに安定した event_id、ビジネスタイムスタンプ、ソースオフセットがあるか、再実行時に元のイベントを読み取るのかソースから再取得するのか、どのようなプライバシーおよび保持要件が適用されるかを確認します。
30秒での回答
不変の生データ(raw)レイヤー、バリデーションルーター、正常データパス、検疫パスを分離します。失敗したすべてのレコードは、証拠、ソース位置、ルールバージョン、理由、状態を保持し、正常なレコードは event_id により冪等に書き込まれます。修正後は、再実行バッチが制御されたルールバージョンを用いて同じ変換および書き込み境界を実行し、レコードの暗黙的な欠落や重複がないことを突合メトリクスで証明します。
ステップごとの詳細解説
1. ルーティング前に事実を保存する
まず、ソース、パーティション/オフセット、受信時刻、event_id、ペイロードのハッシュを含め、受信イベントを不変ストレージまたは再実行可能なログに書き込みます。パースやスキーマのエラーは、破棄するのではなくエラーコードを付与して検疫へルーティングします。通過したレコードは通常のパスを進むため、1つの異常レコードが無関係なバッチやパーティションを停止させることはありません。
2. 検疫を実行可能(actionable)にする
ペイロードまたは制御された参照、失敗したフィールド、ルール名とバージョン、初回失敗時刻、ソース位置、リトライ回数、修復バッチ、および open、ready_for_replay、replayed、rejected などの状態を保存します。機密フィールドは暗号化または最小化し、保持ポリシーを適用します。検疫テーブルは運用キューであり、無制限のアーカイブではありません。
3. 再実行に同一の正確性境界を提供する
修復ルールをバージョン管理し、元のイベントを絶対に上書きしないようにします。再実行ジョブは承認された状態とルールバージョンを選択し、小さなサンプルまたはシャドウターゲットを検証した上で、本番トラフィックで使用されるものと同じ変換・書き込みパスを呼び出します。event_id とビジネスバージョンを冪等性キーとして使用し、競合が発生した場合に upsert、no-op、新規バージョンのいずれとするかを定義します。2回再実行しても同じ結果に収束しなければなりません。
4. 重複、遅延、ポイズンピルを処理する
event_id、ソース位置、または文書化された重複排除ウィンドウを使用して重複を検出します。オフセット単体ではビジネス上の識別子にはなりません。遅延イベントはビジネス時間に基づいてルーティングし、ウォーターマークやバックフィルが下流の結果にどのように影響するかを明記します。ポイズンピルのリトライには上限を設け、担当者への引き渡しや終端拒否状態に遷移させることで、1つのレコードがワーカーの全容量を消費するのを防ぎます。
5. オブザーバビリティで健全性を証明する
正常通過率、ソースおよびルールごとの検疫数、未解決の最古の経過時間、再実行成功率、重複書き込みの競合、エンドツーエンドのレイテンシ、鮮度(freshness)を追跡します。しきい値に基づいてアラートを発報するか、パイプライン全体を停止する前に単一のソースを隔離します。バッチまたはオフセット範囲ごとに、生データ、正常、検疫、再実行、拒否の件数を突合(レコンサイル)します。説明のつかない不一致はインシデントとして扱います。
優れた回答例
まず、イベントの識別性と整合性要件を明確にします。次に、生のイベントを不変の形式で永続化し、スキーマ、ビジネスルール、重複、順序を検証し、失敗したものを破棄せずに検疫ストアにルーティングします。検疫レコードには、ペイロード参照、ソースオフセット、ルールバージョン、詳細な理由、ライフサイクル状態が保持されます。正常なレコードと再実行されたレコードは、event_id とビジネスバージョンをキーとする同一の冪等書き込みパスを共有します。修復時は元のイベントを変更せずに承認済みの再実行バッチを作成します。少量のサンプルでテストし、ポイズンピルのリトライに上限を設け、遅延イベントの挙動を明確にします。最後に、機密フィールドを保護し保持期間を強制しながら、検疫の滞留時間、再実行の成功率、書き込み競合、鮮度、件数の突合を監視します。
よくある間違い
- 失敗した行を破棄する、またはエラー文字列のみをログに記録する。
- ソース位置、イベント識別子、ルールバージョンを省略する。
- 本番トラフィックから乖離する可能性のある別の変換処理として再実行を実装する。
- 上限や担当者を決めずにポイズンピルをリトライし続ける。
- 状態、保持期間、完了条件を設けずに、検疫をゴミ箱のように扱う。
- ソース、ルール、経過時間のディメンションを見ずに、集計された成功率のみを監視する。
フォローアップ質問と回答
検疫内の個人データをどのように保護しますか?
診断に必要な最小限のフィールドのみを保持し、機密ペイロードを暗号化し、アクセスを制限し、制御された参照を通じて元のデータを取得します。読み取りを監査し、保持期限が来たら削除を強制します。
再実行中に新しいデータが到着した場合はどうしますか?
独立した再実行バッチと明示的なイベントバージョンを使用します。冪等性キーによってマージします。順序が重要な場合は、パーティションまたはエンティティの境界を定義し、競合時の決定を記録します。
パイプライン全体を停止するのはどのような場合ですか?
破壊的(breaking)なスキーマ変更、ターゲットの利用不可、または正常なデータを汚染する恐れがあるデータ破損のリスクがある場合のみです。通常は、他のパスを継続させたまま、単一の異常なソースまたはルールを隔離する必要があります。
データの欠落がなかったことをどのように証明しますか?
入力バッチまたはオフセット範囲ごとに台帳(ledger)を作成し、生データ、正常、検疫、再実行、拒否の件数を突合します。event_id のセットをサンプリングし、未解決の経過時間を品質 SLO に含めます。