業務は正常なのに収集が失敗する
一言でいうと
ラベルは説明を添えるメモではなく、時系列のアドレスです。サンプル制限は収集の予算を守りますが、どの情報が失われたかまでは判断してくれません。
なぜ必要なのか
決済サービスを改善する際、リクエストのメトリクスにユーザー識別子を付けました。特定の顧客の問題を探しやすくなると思ったからです。 小さな開発環境ではうまく見えていたのに、ユーザーが増えると監視対象がdownと表示されます。サービスのヘルスチェック用のアドレスはHTTP 200で、決済プロセスも生きています。ネットワーク障害だと考えて再起動すると、しばらくは良くなったように見えますが、同じラベルの組み合わせがまた積み上がると、問題も戻ってきます。まず、どの段階で収集を拒否したのかを読み取る必要があります。
Prometheusの時系列は、メトリクス名とラベルの全体の集合で区別されます。同じ名前のカウンターでも、user_idが違えば別の時系列です。routeが同じだからといって、自動的に合算されることはありません。人間はラベルの列を1つ追加しただけだと思う変更が、ストレージではアドレスの数の増加になります。ユーザー数だけでなく、パス・ステータスコード・インスタンスとの実際の組み合わせも重要です。取りうる組み合わせの積は、上限を見積もる出発点であって、常に観測される正確な数ではありません。
どう動くのか
今回のラボでは、最大で12人の合成ユーザーだけを使います。実際の個人情報は収集せず、過度なメモリ負荷も生じさせません。基準のエクスポーターは、ユーザー4人分のリクエストカウンターと、業務状態のgaugeを1つ公開します。1回のレスポンスには5つのサンプルがあります。ユーザー数を12人に増やすと、同じメトリクス名でも、カウンター12サンプルとgauge1つの、合計13サンプルになります。別に用意した固定の対照ターゲットは、最後まで同じ値を出力し続けます。
| 観測する場所 | 今回の実験で答える質問 |
|---|---|
| エクスポーターの/healthzと/metrics | プロセスは正常に応答しているか、どんな元データを提供しているか |
| 現在適用されているscrape設定 | どのターゲットと、どんな制限・フィルターを実際に使っているか |
| ターゲットAPIのhealthとlastError | 直近の収集は成功したか、失敗したなら理由は何か |
| 現在のPromQLの結果 | 保存されたサンプルを、どんなラベルと値で読んでいるか |
sample_limitは、1回のスクレイプで受け入れるサンプル数を制限します。metric relabelingのあとの数が上限を超えると、そのスクレイプ全体が失敗する設定です。先頭の8つだけを保存して、残りを正常に切り捨ててくれるページサイズのようなものではありません。ラボの上限を8にすると、5サンプルの基準線は通過しますが、13サンプルのレスポンスは拒否されます。上限を超えたという直近のエラーとup=0を結びつけたうえで、業務のHTTP 200と、対照ターゲットのup=1も一緒に残します。
sample_limitを16に上げると、今回の小さなレスポンスはまた取り込まれます。これは原因を絞り込むための有用な実験ですが、計装の設計が良くなった証拠ではありません。現在のリクエストの時系列は、依然として12個です。ユーザーが増え続ける本番環境で制限だけを上げても、次の上限に達する時点を先送りするだけかもしれません。8と16は、原理を観測するためのラボ用の数字であり、すべてのサービスに適用できる本番の推奨値ではありません。実際の予算は、収集間隔・ターゲット数・メトリクスの種類・保持期間・クエリのパターンとあわせて測定する必要があります。
メトリクス名も、シグナルの単位を伝えます。リクエスト回数は累積のcounterで、名前はpca_checkout_requests_totalです。現在の業務が正常かどうかは、gaugeのpca_business_okです。累積カウンターの値の合計は、この実験で情報が保たれていることを確認するための値であって、毎秒のスループットではありません。毎秒のスループットを求めるときは、各カウンターのresetを考慮したrateを先に計算してから集計するという、別の問題を解く必要があります。小さな静的入力で2つの概念を混同しないようにすることが、今回の設計の意図です。
現場での姿
ユーザーID、注文番号、完全なURLのように、値の範囲が大きくなるラベルは、便利な検索機能のように見えます。しかし、メトリクスは、すべてのイベントの詳細な記録を保管するストレージとは役割が違います。パスのテンプレートや、限定されたステータス分類のように、運用上の質問に必要なディメンションを先に設計し、個々のイベントの文脈は、適切なログ・トレースと結びつける方法を検討してください。機微な識別子がメトリクスに入ると、アクセス制御や、保持・削除の範囲も複雑になります。今回のu1のような合成値は、実際の個人情報を入れても構わないという意味ではありません。
障害報告には、downという言葉だけを書かないでください。「業務のHTTPは正常、対照群の収集も正常、該当jobの元のレスポンスは13サンプルで、適用された上限8のためスクレイプが失敗した」と書けば、次の行動が変わります。プロセスを再起動するか、ネットワークを調査するか、計装の設計を直すかを判断する根拠が得られます。1回の観測が一致していても、確認した時刻と直近のスクレイプの時刻を一緒に見ないと、以前の結果を新しい変更の結果と誤解してしまいます。
次のラボですること
正常な基準線から、元のレスポンス・適用された設定・収集の結果を保存します。ラベルの数を増やして上限による拒否を観測し、制限を一時的に上げて、同じ元データが実際に取り込まれるかを確認します。そのあと、2つの誤った修正と、ソースの計装の修正を比較します。すべてのサービスは、個人VMのloopbackにだけバインドし、他の人の監視サーバーや本番の設定には触れません。ラボが終わるとVMとTSDBは回収されるので、必要な観測は有効期限が切れる前に別に保管してください。
公式ドキュメント
- Prometheus設定: sample_limitが適用される時点と、失敗の範囲を読んでください。
- 計装指針: 観測したい質問と、ラベルのディメンションのコストをあわせて検討してください。
- メトリクスとラベルの名前: 単位と意味を名前に表すルールを確認してください。