プロンプトとコンテキスト
あるワーカーがキューから100件のイベントを消費し、集約後に下流のAPI呼び出しを1回行います。各イベントは異なるTraceに属している可能性があり、ワーカーはスケジューラやリプレイによってトリガーされることもあります。無関係なリクエストが1つの親子ツリーを形成しているかのように見せかけることなく、すべてのソースが検出可能な状態を維持できるようにトレースをモデル化してください。
OpenTelemetryでは、Spanをツリーを形成可能なオペレーションとして説明しており、各Spanには0個以上のLinksを含めることができます。その概要では、複数の受信Spanによって開始されるバッチ処理がLinksの典型的なユースケースとして挙げられています。
面接官がテストしていること
候補者は、parentが1つの現在のコンテキストであるのに対し、Linkは親子関係を持たずに関連する因果関係を表すものであることを理解している必要があります。また、有用なメトリクスやログの相関関係を維持しながら、リンク数、サンプリング、カーディナリティの高い属性を制御できる必要があります。
最初に尋ねるべき明確化のための質問
- バッチには複数のテナント、セキュリティレベル、またはビジネスタイプが含まれる可能性がありますか?
- 下流への呼び出しは1つの集約されたオペレーションですか、それともイベントごとのままにできますか?
- 目標はイベントごとのアカウンタビリティ、レイテンシ分析、またはバッチスループットのどれですか?
- サンプリングはイングレス(受信時)に決定されますか、それともワーカーが選択したソースコンテキストを保持できますか?
- Linkの属性にイベントID、テナントID、または機密フィールドを含めることはできますか?
30秒の回答フレームワーク
「バッチ処理のSpanは、ワーカーまたはスケジューラのコンテキストをそのparentとして使用します。100件の受信SpanContextは、単一の親子チェーンを形成することなく共同で1つのバッチオペレーションを引き起こしたため、Linksになります。必要な低カーディナリティの属性のみを保持し、リンク制限を適用して、切り捨て(truncation)をカウントします。バッチメトリクスはサイズ、キュー待機時間、処理時間、下流レイテンシ、失敗、リトライをカバーし、ログはバッチIDとイベントハッシュで関連付けます。機密性の高いテナントフィールドはフィルタリングされ、失敗またはリプレイされたバッチにはサンプリングのセーフティパスが用意されます。」
ステップバイステップの詳細解説
ステップ 1: parentとLinkを分離する
parentは現在のオペレーションがどの単一のSpanを継続しているかを示し、Traceツリーを形成してそのTraceIdを継承します。Linkは、同じまたは別のTraceからの関連する1つのSpanContextを記録します。バッチ内でソース同士が対等(ピア)である場合、最初のイベントをparentとして選択すると誤ったツリーが作成されてしまいます。
Batch-processing Span
parent: worker / scheduler context
links: event-1 SpanContext ... event-100 SpanContextステップ 2: 境界を越えてSpanContextを保持する
メッセージヘッダーからTraceContextを抽出し、そのフォーマットとサンプリングフラグを検証して、Linkを作成します。完全なメッセージ、ユーザー入力、または生のトークンをLinkの属性に含めないでください。コンテキストが存在しない場合は、TraceIdを捏造するのではなく「ソースコンテキストなし」をカウントします。
ステップ 3: リンクのサイズとコストを制限する
100個のリンクは単なる例示的な制限にすぎず、本番環境のバッチはさらに大きくなる可能性があります。SDKのリンク数制限またはアプリケーション側の上限を設定し、代表的なエラー、リトライ、リプレイ、または優先テナントのソースを保持し、ドロップされたリンク数を記録します。切り捨てはバッチメトリクスとログで可視化されている必要があります。
ステップ 4: バッチSpanのライフサイクルを定義する
Spanはバッチの待機、デシリアライズ、集約、下流の呼び出し、およびコミットをカバーします。フェーズイベントまたはメトリクスを追加してください。作成されたすべてのSpanは、成功、失敗、キャンセル、または部分コミットのいずれかで終了しなければなりません。単一の低速なイベントによってバッチのフェーズ境界が隠されてはなりません。
ステップ 5: サンプリングと失敗を診断可能にする
イングレスサンプリングによってソースTraceが破棄される可能性があるため、ワーカーには失敗、リトライ、デッドレター、手動リプレイに対するセーフティポリシーが必要です。Span作成時に存在するLinksはサンプリングに影響を与える可能性がありますが、後から追加されたLinksは影響を与えない場合があります。その順序とフォールバックを明示的にしてください。
ステップ 6: トレース、メトリクス、ログに異なる役割を与える
トレースは1つのバッチの因果関係を説明します。メトリクスはバッチサイズ、キュー待機時間、処理レイテンシ、成功/失敗、および切り捨てを保持します。ログはバッチID、イベントハッシュ、リプレイIDを使用して、制御されたサンプルを特定します。イベントIDを非バウンドなメトリクスラベルとして使用しないでください。
ステップ 7: テナントとプライバシーを分離する
マルチテナントバッチの場合、Linksやログでは不可逆なハッシュまたは内部参照を使用し、エクスポート前に属性をフィルタリングします。セキュリティレベルを混在させることができない場合は、低権限の閲覧者が別のテナントのコンテキストをたどることができないよう、バッチをテナントまたは権限ごとに分割します。
ステップ 8: クエリと障害を検証する
単一ソース、混在するTrace、コンテキストの欠落、リンクのオーバーフロー、サンプリングによる欠落、下流のリトライ、部分的な失敗、デッドレター、リプレイをテストします。バッチSpanが保持されたソースTraceにジャンプできること、およびメトリクスによって切り捨てられたバッチやサンプリングされなかったバッチを特定できることを確認します。
質の高い模範回答
「バッチSpanはワーカーまたはスケジューラをparentとして使用し、各メッセージのSpanContextはLinkとなります。これにより、親子ツリーを捏造することなく、100件のイベントが共同で1回の下流呼び出しを引き起こしたという事実が保持されます。リンクを制限してドロップ数をカウントし、テナントや機密性の高い属性をフィルタリングし、バッチサイズ、キュー待機時間、下流レイテンシ、失敗、リトライにメトリクスを使用します。ログはバッチIDおよびリプレイIDと相関させ、失敗したバッチにはサンプリング保護を適用します。テストでは、コンテキストの欠落、混在するTrace、オーバーフロー、リプレイをカバーします。」
よくある間違い
- 最初のメッセージをparentとして選択する → 誤った因果関係 → 共通のワーカーparentを使用し、ソースにはLinksを使用する。
- 完全なメッセージをLinkに含める → プライバシーおよびコストの漏洩 → サニタイズされた必要な低カーディナリティのフィールドのみを保持する。
- 制限なしでLinksを追加する → 非バウンドなSpanおよびエクスポートコスト → 上限を設定し、切り捨てを測定する。
- 成功時のみSpanを終了する → 失敗やキャンセルによってSpanが開いたままになる → finallyブロックまたはスコープ内で終了する。
- イベントIDをメトリクスラベルとして使用する → カーディナリティの爆発 → 詳細はログまたはトレースに保持する。
- 後から追加したLinksが常にサンプリングに影響を与えると仮定する → 重要なソースが消失する → Span作成前にサンプリングコンテキストを準備する。
フォローアップ質問と効果的な回答
フォローアップ 1: 1件のメッセージのバッチにもLinkが必要ですか?
そのメッセージのコンテキストをparentとして使用できます。ワーカーが独立したライフタイムを持つ場合は、ワーカーのparentに加えて1つのLinkを持たせることも有効です。バッチが直接の子オペレーションであるかどうかに基づいて選択してください。
フォローアップ 2: Linksは異なるTraceをマージしますか?
いいえ。関連性を表現し、各TraceIdを保持します。クエリシステムは、LinkからソースTraceへのナビゲーションを提供する必要があります。
フォローアップ 3: どのソースが切り捨てを生き残りますか(保持されますか)?
エラー、リトライ、リプレイ、優先テナント、または決定論的サンプルを優先し、合計数とドロップ数を記録します。最初のN件を暗黙的に保持することはバイアスをもたらします。
フォローアップ 4: 失敗したバッチをどのように診断しますか?
失敗およびデッドレターのリプレイに独立したバッチ/リプレイIDを付与し、制御されたエラーソースのLinksまたはサマリーを保持し、失敗タイプをメトリクスに含めます。
フォローアップ 5: Linkにtenant.idを含めることはできますか?
アクセス権、カーディナリティ、プライバシーのレビューを経た後でのみ可能です。テナント間のエクスポートでは通常ハッシュ化または削除され、大量のメトリクスラベルにしてはなりません。