プロンプトとコンテキスト
あるサービスでOpenTelemetryの導入が進められており、チームはuserid、requestid、および完全なURLをメトリクス属性として追加したいと考えています。カーディナリティ予算を設計し、何を残すべきか、制限に達したときに何が起きるか、そしてアラートの有用性が保たれていることをどのように証明するかを説明してください。
OpenTelemetryのメトリクスは、属性の組み合わせから時系列を生成します。SDKのカーディナリティ制限は、収集サイクル中に1つのメトリクスで追跡されるメトリクスポイントに対するハードリミットです。高カーディナリティのフィールドはメモリ、エクスポート、ストレージ、およびクエリのコストを急増させるため、予算管理によってコストと診断価値の双方を保護する必要があります。
面接官がテストしていること
面接官は、メトリクス、ログ、トレースの各ディメンションを明確に分離できるか、単一フィールドのカウントではなく組み合わせとして理解しているか、ハードリミットと縮退動作を設計できるか、そしてサービスグラフ、アラート、サンプリング、プライバシーの制約を運用可能にできるかをテストしています。
明確化のための質問
メトリクスの目的、クエリウィンドウ、アラートレイテンシ、テナント数、エンドポイント数、収集間隔、バックエンドの保持期間、および予算を確認します。トレースまたはログの相関フィールドがすでに存在するか、どの識別フィールドがプライバシーに配慮すべきか、制限時に新しい値、古い値、または集計精度のどれを優先すべきかを質問します。
30秒の回答
「すべてのコンテキストをメトリクスに詰め込むのではなく、メトリクスの目的に応じて許可されるディメンションを定義します。service、region、ルートテンプレート、ステータスクラスなど、グループ化されたアラートをサポートする安定的で低カーディナリティなフィールドを維持し、userid、requestid、生のURLはトレースやログに配置します。メトリクスごとにカーディナリティ制限、コストアラート、飽和シグナルを設定し、明示的な集約または破棄ポリシーを設けます。最後に、過去のトラフィックをリプレイしてアラートの再現率、誤検知、クエリコスト、プライバシーを測定します。」
詳細な回答
ステップ 1: メトリクスの問いを定義する
問いを書き出します:エラー率は上昇しているか、どのルートが影響を受けているか、どのリージョンが低下しているか、あるいは1つのユーザーリクエストで何が起きたか? 最初のいくつかのケースはメトリクスに適していますが、最後のケースはトレースまたはログに属します。
ステップ 2: 組み合わせのカーディナリティを見積もる
カーディナリティは各フィールドの値の合計ではなく、属性の組み合わせの一意な集合です。service、region、ルートテンプレート、ステータス、メソッド、テナント層の積を見積もり、実際の分布、ロングテール、バーストトラフィックで補正します。
ステップ 3: フィールドをレイヤー化する
集計可能な安定したフィールドを維持し、ユーザー、リクエスト、完全なURLはトレースやログに配置します。高カーディナリティのテナント識別子については、アクセス制御と調査のニーズが満たされる場合にのみバケッティング、ハッシュ化、またはサンプリングを使用します。生のパスパラメータから無制限の時系列を作成してはなりません。
ステップ 4: SDKとバックエンドの予算を設定する
最後に切り詰めるだけではなく、SDK、Collector、時系列バックエンド、およびクエリレイヤーで予算を設定します。OpenTelemetryのメトリクスカーディナリティ制限はハードキャップであり、保持される属性セットは実装とアラートで観測可能でなければなりません。
ステップ 5: 制限時の動作を定義する
どの組み合わせを残すか、オーバーフローバケットを使用するか、新しいセットを破棄するか、そしてその決定がどのようにカウントされるかを指定します。ポリシーは安定的かつ説明可能で、飽和シグナルを備えている必要があり、サイレントな損失は許容されません。
ステップ 6: 適切なシグナルに相関関係を持たせる
リクエストにはtraceid、生のURLやuseridにはログ、メトリクスからサンプルへ遷移するにはExemplar(エグゼンプラ)やリンクを使用します。メトリクスは傾向とアラートを提供するものであり、リクエストごとの診断を置き換えるものではありません。
ステップ 7: サービスグラフとコストを予算化する
サービスグラフや自動計装は多くのメトリクスファミリを生成する可能性があります。エッジ、クライアント、サーバー、エラーステートに個別の予算を設定し、エクスポート頻度、保持期間、高カーディナリティ属性を制御します。合計のみを見るのではなく、コストレポートをサービスやメトリクスに帰属させます。
ステップ 8: アラートの品質とプライバシーを検証する
トラフィックをリプレイし障害を注入して、予算の有無による再現率、誤検知、レイテンシ、クエリコストを比較します。墨消し(リダクション)、アクセス制御、削除リクエスト、テナントの分離を確認し、飽和、構成変更、データ損失を追跡可能にします。
模範解答
トレンドアラートと単一リクエストの調査を分離します。service、region、ルートテンプレート、メソッド、ステータスクラスは通常、安定的で低カーディナリティなメトリクス属性です。userid、requestid、パラメータ化されたURLはトレース、ログ、Exemplarに属します。属性の組み合わせの積を見積もり、ロングテールトラフィックで補正した上で、SDK、Collector、バックエンドでカーディナリティとコストの予算を設定します。制限時には、サイレントに失敗させるのではなく明示的なオーバーフローまたは破棄ポリシーを使用し、飽和を記録します。サービスグラフのエッジ、クライアント、エラーステートを個別に予算化し、収集と保持を制御します。本番展開前に、トラフィックをリプレイして高カーディナリティおよび障害ケースを注入し、アラートの再現率、誤検知、クエリコスト、プライバシー、テナント分離を比較検証します。
よくある間違い
各フィールドを個別にカウントする
時系列は組み合わせから生じます。複数の中カーディナリティフィールドが掛け合わさることで爆発的な増加につながる可能性があるため、組み合わせ、ロングテール、バーストを見積もる必要があります。
すべてのメトリクスにuser_idを含める
ユーザーレベルの調査はトレースとログに属します。メトリクスに識別ディメンションを含めると、コスト、プライバシーリスク、クエリノイズが増加します。
制限時にデータをサイレントに破棄する
サイレントロスが発生すると、アラートが正常に見えてしまいます。飽和、保持ルール、構成バージョンを記録し、縮退状態での診断をテストしてください。
フォローアップの質問と回答
ルートテンプレートは完全なURLとどう異なるべきですか?
パスパラメータによって新しい時系列が作成されないように、メトリクスには正規化されたルートテンプレートを使用します。完全なURLは、プライバシーに配慮した墨消しを行った上で、制御されたログやトレースに送信します。
制限時は古い属性セットと新しい属性セットのどちらを保持すべきですか?
アラートと集約エンジンの仕様に依存しますが、ルールは固定され、説明可能で、観測可能でなければなりません。インスタンス間で動作が不整合にならないよう、オーバーフローをカウントします。
メトリクス、トレース、ログをどのように相関させますか?
サンプルをリンクするにはtraceid、spanid、またはExemplarを使用します。メトリクスには安定したディメンションを維持し、ログやトレースにはリクエストコンテキストを保持し、ナビゲーション時にはアクセス境界を強制します。
なぜサービスグラフには独自の予算が必要なのですか?
自動生成されるエッジ、クライアント、エラーディメンションは時系列を増殖させます。グラフがビジネスメトリクスを圧迫しないよう、エッジタイプ、収集頻度、保持期間ごとに予算を分割します。
予算設定が障害を隠蔽していないことをどのように証明しますか?
実トラフィックをリプレイし、高カーディナリティ、エラースパイク、テナントのロングテールを注入します。飽和イベントを監視しながら、予算適用前後の再現率、誤検知、レイテンシ、クエリ結果を比較します。
メトリクスではなくログを追加すべきなのはどのような場合ですか?
単一のリクエスト、生の入力、またはユーザーコンテキストが必要な場合は、制御されたログまたはトレースを使用します。メトリクスは集計可能な傾向とアラート用ディメンションを保持すべきです。