問題とスコープ
単一リクエストのレイテンシ分布、合成リクエスト、およびサービス目標について議論します。毎分100,000リクエスト、平均80 ms、p95が180 ms、p99が2秒と仮定します。これらは面接用の前提条件であり、業界のベンチマークではありません。特定のベンダーツールではなく、推論と検証に焦点を当ててください。
面接官が評価していること
面接官は、平均値が作業の総量を表すものであり、分布の形状を表すものではないことを理解しているかを見ています。テールのリクエストは、テナント、ルート、依存関係、リージョン、リクエストサイズ、またはリトライパスごとに偏留する可能性があります。優れた回答では、測定境界、集計のディメンション、ユーザーへの影響、サーバー側の原因、および実用的なSLOを定義します。
確認すべき質問
- レイテンシは最初の1バイト(TTFB)で測定されていますか、それとも完全なレスポンスで測定されていますか?
- p99はインスタンス別、ルート別、リージョン別、またはサービス全体ですか?また、どの時間枠(ウィンドウ)ですか?
- タイムアウト、キャンセル、リトライ、キャッシュヒットは含まれていますか?
- テールにおいて、リクエストサイズ、テナント、依存関係の呼び出し、またはエラーに変化はありますか?
- 目標は全体を改善することですか、それともクリティカルパスのテールバジェットを保護することですか?
30秒の回答フレームワーク
「80 msの平均値と2秒のp99は共存し得ます。最も遅い1%がユーザーやアップストリームのタイムアウトを引き起こす可能性があります。まず測定境界とウィンドウを確定し、ルート、リージョン、インスタンス、テナント、リクエストサイズ、依存関係ごとに分布を分割します。次にキュー、プール、GC、ディスク、ロック、ダウンストリーム呼び出し、リトライを調査します。修正はボトルネックに合わせて行います。有界キュー、適切なタイムアウト、バッチ処理やキャッシング、直列依存関係の削減、ノイズの多いテナントの隔離、有限のリトライバジェットなどです。p95/p99のSLOとエラーバジェットで検証します。」
ステップバイステップの詳細設計
観測ポイントを定義します:クライアントの合計時間、エッジからサービス、サービス処理、ダウンストリームの待機時間、レスポンス転送時間。ファーストバイトまたは完全レスポンスのセマンティクスを選択し、モノトニッククロックを使用し、サンプリングを文書化します。タイムアウトとキャンセルは個別にカウントし、1つのユーザーアクションが複数の独立した成功としてカウントされないようにリトライを元のリクエストに関連付けます。
パーセンタイルはリクエストサンプルから算出する必要があります。インスタンスごとのp99値を平均化することは無効です。ルート、ステータス、リージョン、インスタンス、テナント、リクエストサイズ、依存関係ごとにパーセンタイルとサンプル数を分類します。短いウィンドウはリグレッションを明らかにしますがジッターが発生します。長いウィンドウはSLOを安定させますが不正なリリースを隠してしまう可能性があります。両方を示してください。
合成リクエストはテールを増幅させます。直列呼び出しは各ステージを加算し、並行呼び出しは子レイテンシの最大値付近で完了します。各ステージにバジェットを割り当て、トレーススパンを記録し、ファンアウトを調査します。単一サービスの平均からエンドツーエンドのページ体験を予測することはできません。
推測する前に相関関係を診断します。キュー滞留時間の増加はキャパシティや受付プレッシャーを示唆し、プール待機時間は並行性の制限を示します。GC、ディスク、CPUジッターはテールを生み出し、遅いダウンストリームのp99はアップストリームに伝播します。リクエスト属性によって成功サンプルとタイムアウトサンプルを比較し、遅いトレースのために制御されたコンテキストを保持します。
原因に応じた対策を講じます。直列呼び出しの削減、キャッシング、またはバッチ処理によって固定オーバーヘッドを削減します。有界な並行性、バックプレッシャー、テナント隔離によって輻輳を防ぎます。有限のタイムアウトとジッター付きリトライによってリトライストームを回避します。非同期処理によって予測不可能なタスクを同期パスから除外します。スレッドやレプリカを増やすだけでは、かえってテールを伸ばしてしまうことがあります。
SLOは、300 ms未満が99.9%など、しきい値を満たす対象リクエストの割合として表現します。エラーバジェットは、リリースの判断においてレイテンシ違反とエラーを統合します。そのIngress、ステータス、キャッシュセマンティクス、およびウィンドウを明示します。平均値のみのターゲットは、最も遅いユーザーが影響を受けている間も正常(グリーン)のままになる可能性があります。
リリースや障害訓練(ドリル)で分布の変化を検証します。前後のp50、p95、p99、最大値、タイムアウト率、サンプル数を比較します。依存関係のレイテンシを注入し、大規模テナントのリクエストを作成し、プールを枯渇させて隔離とデグラデーションを検証します。復旧後は、平均値だけでなくキューの排出状況やリトライの増幅を検査します。
高品質なサンプル回答
「80 msの平均値と2秒のp99は、明確なロングテールを意味します。最も遅い1%がユーザーやアップストリームのタイムアウトを引き起こす可能性があります。まずタイミング境界を標準化し、ファーストバイト、完全レスポンス、キャンセル、リトライを分離した上で、ルート、リージョン、インスタンス、テナント、リクエストサイズ、依存関係ごとに分割します。また、ページは直列呼び出しを合算し、並行呼び出しの最大値を取るため、トレーススパンにはステージごとのバジェットが必要です。
キュー、プール、GC、ディスク、ダウンストリームのレイテンシを特定した後、有界な並行性、キャッシングやバッチ処理、直列依存関係の削減、テナント隔離、有限のリトライを適用します。300 ms未満を99.9%とするSLO、エラーバジェット、リリース間でのパーセンタイル比較を用いて検証し、エラーや正確性の問題を隠すことなくテールが改善されることを確認します。」
よくある間違い
- 平均値のみを報告する → テールにいるユーザーが見えなくなる → パーセンタイル、サンプル数、タイムアウトを報告する。
- インスタンスのp99値を平均化する → パーセンタイルは線形に平均化できない → サンプルまたはヒストグラムのバケットを正しく集計する。
- リトライを新しいユーザーリクエストとしてカウントする → 負荷と体験が不正確に表現される → 試行を元のリクエストに関連付ける。
- サーバー時間のみを測定する → ネットワーク、キュー、転送時間が除外される → エンドツーエンドの境界を定義する。
- 制限なくスレッドを追加する → 競合とキューイングによってテールが伸びる → 有界な並行性とバックプレッシャーを使用する。
- すべてのタイムアウトを盲目的にリトライする → リトライストームにより依存関係が崩壊する → バジェット、ジッター、デッドラインを使用する。
- グローバルなSLOを1つだけ設定する → 特定のテナントやリージョンが密かに劣化する可能性がある → 重要なディメンションごとにスライスする。
- リリース後に平均値のみを監視する → リグレッションが隠れたままになる → 複数のパーセンタイルとウィンドウを比較する。
フォローアップの質問と回答
フォローアップ1:なぜp99は最も遅いリクエストではないのですか?
p99は、サンプルの約99%がその値以下であり、約1%がそれより遅いことを意味します。最大値は単一の異常値やサンプルサイズに敏感であるため、両者には異なる用途があります。
フォローアップ2:ページに5つの並行呼び出しがあります。体験をどのように推定しますか?
並行ステージは、子レイテンシの最大値にクライアントのスケジューリングと転送時間を加えた値に近くなります。ページの合計時間を測定し、どの子呼び出しが最も頻繁に最大値となるかをトレースします。
フォローアップ3:テールレイテンシが高くても許容されるのはどのような場合ですか?
オフラインのエクスポートや低頻度のバックグラウンドジョブでは、レイテンシと引き換えにスループットを優先する場合があります。インタラクティブなクリティカルパスでは通常許容されません。リクエストクラスごとにSLOを定義してください。
フォローアップ4:なぜヒストグラムは平均値よりも優れているのですか?
ヒストグラムはバケットと分布の形状を保持するため、複数のパーセンタイル推定やテールの詳細な検査が可能です。集計時にはバケットの境界とサンプル数に引き続き注意が必要です。
フォローアップ5:キューによるテールとダウンストリームによるテールをどのように切り分けますか?
待機時間、処理時間、ダウンストリームのスパンを個別に記録します。キュー時間とサービス時間が同時に増加している場合はキャパシティの問題を示唆し、ダウンストリームのみが増加している場合はその依存関係またはそのリトライに原因があります。
フォローアップ6:エラーバジェットはレイテンシ対策にどのように役立ちますか?
しきい値違反をバジェットの消費としてカウントします。急速な消費はリスクの高いリリースを一時停止し、テール修正を優先させます。残りのバジェットは制御された実験を可能にします。