Dev Study
← 性能分析の土台
レッスン 2 / 10·約 9 分·第13期 性能分析

平均は、誰のことも指していない

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理今ここ
  7. DB保存

前回、レイテンシとスループットの2つでは足りないことを見ました。今回は、そのレイテンシを1つの数字にまとめる方法を見ます。

まず結論

平均は計算で作られた値なので、実在の1回と一致する保証がありません。パーセンタイルは並べて何本目かを取る値なので、必ず実在の1回を指します。

ただし平均が無意味なのではありません。合計を戻せるのは平均だけです。そして p99 が数えているのはリクエストであって利用者ではない、という問題が残ります。

? 読む前に予測

APIの応答時間を640回測り、平均を出しました。平均と同じ値だった回は何回あるでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

計算で作る値と、選び出す値

レイテンシは1回ごとに違う値になります。何千回ぶんの測定を1つの数字へ縮める道具は2種類あります。

1つ目は計算して作るやり方です。全部を足して件数で割る、つまり平均。出てくる値は計算の産物なので、実在の1回と一致する必要がありません。

2つ目は並べて選び出すやり方です。小さい順に並べ、下から何本目かを取り出す。パーセンタイル、つまり順序統計量です。位置で選ぶので、出てくるのは必ず実在の1回です。

この違いは報告の意味を変えます。「平均 100 ms」は誰の体験でもない可能性がある一方、「p99 は 800 ms」は確かに 800 ms かかった回があったという報告です。

1つの数字に縮める2つのやり方
測定した値の並び1回ごとに違う数
足して割る
平均計算で作る。実在の1回とは限らない
合計が戻せる平均×件数=合計
並べて何本目かを取る
パーセンタイル選び出す。必ず実在の1回
合計は戻せない中央値×件数=合計ではない
  • 優劣ではなく、答えている問いが違う
具体実物

10件で手計算できる例

10回の応答時間が、9回は 10 ms、1回だけ 1000 ms だったとします。

本教材の測定環境(Docker Desktop の Linux VM)での計算結果コマンド出力
data : [10, 10, 10, 10, 10, 10, 10, 10, 10, 1000]
n : 10 sum : 1090
mean : 109.0 mean in data? : False
p50 (nearest-rank): 10 is an actual observed value? True
p90 (nearest-rank): 10 is an actual observed value? True
p99 (nearest-rank): 1000 is an actual observed value? True

平均は 109.0 ですが、109 を経験したリクエストはありません。 このデータには 10 と 1000 しか無いからです。一方 p50・p90・p99 は3つとも実際に観測された値でした。

では平均が役立たずかというと、そうではありません。同じデータで合計を戻します。

合計を復元できるのはどちらかコマンド出力
total time for all 10 requests = mean * n = 1090.0 = sum = 1090
p50 * n = 100 <- underestimates the real total by 990

平均に件数を掛けると総量が戻ります。 中央値では 100 で、実際の 1090 に対し約11分の1の過小評価です。総量を見積もるとき、正しい道具は平均のほうです。

✓ ここまでの確認

「パーセンタイルは平均より優れているので平均は使うべきでない」という説明の評価はどれですか。

抽象原理

平均と中央値の大小は、分布が決める

「跳ねた回が平均を押し上げるから、平均は中央値より大きい」と言われることがあります。これは分布によります。

サービス時間を 50 ms に固定したまま同時接続を32本にしたときの640件で調べました。

本教材の測定環境(Docker Desktop の Linux VM、640件、サービス時間50ms固定)コマンド出力
n=640 measured latencies (ms), conc=32, fixed 50ms service time
mean = 395.820
mean appears in the measured data? False
p50 = 415.801 present in data? True
p90 = 425.358 present in data? True
p95 = 776.565 present in data? True
p99 = 789.192 present in data? True
min=50.712 max=1152.997
nearest measured values around the mean: 379.430 and 408.203

640回測って、平均 395.820 ms に一致する回はありません。 最も近い実測値は 379.430 と 408.203 で、平均はその隙間に落ちています。パーセンタイルは4つとも実在の1回です。

そして平均(395.8)が p50(415.8)より小さい。 ここでは平均のほうが楽観的でした。「平均は跳ねに引っ張られて大きくなる」では説明がつきません。どちらが大きいかは分布の形で決まります。

具体実物

p99 が数えているのは、リクエストであって利用者ではない

この回で一番効く区別です。パーセンタイルはリクエストを並べて何本目かを取る値でした。だから単位はリクエストです。利用者ではありません。

Google SRE Book の Chapter 6 は、平均だけで監視系を組むことの危うさをこう書いています。

If you run a web service with an average latency of 100 ms at 1,000 requests per second, 1% of requests might easily take 5 seconds. If your users depend on several such web services to render their page, the 99th percentile of one backend can easily become the median response of your frontend.

後半が核心です。1つのバックエンドの99パーセンタイルが、フロントエンドでは中央値になりうる。 条件は「1つの画面を描くのに複数のそうしたサービスに依存しているなら」です。

1画面が複数のリクエストを出すなら、1本でも遅い回に当たれば画面全体が遅れます。 画面が待つのは全部そろってからです。本数が増えるほど当たる機会も増えます。

✓ ここまでの確認

「p99 が 800 ms なので、影響を受けるのは利用者の1%だけ」という報告の評価はどれですか。

⇄ 2つを見比べる
具体例 A

レイテンシの平均とパーセンタイル

本教材の測定環境で640件を測ったところ、平均 395.820 ms に一致する回は1回もありませんでした。パーセンタイルは順序統計量なので、選ばれた値は実在の1回でした。

640件のレイテンシ(Docker Desktop の Linux VM、サービス時間50ms固定)表
指標 値(ms) 実測値の中にあるか
mean 395.820 無い
p50 415.801 ある
p99 789.192 ある
具体例 B

ならし計算量と、1回ごとの実測

アルゴリズム編『ならし計算量は、平均ではない』の実測では、list への追加は最大の1回が 19208 ns でも、20万回の平均は 70.1 ns でした。ならした数字は跳ねを合計の中に埋めています。

list への追加20万回(アルゴリズム編の実測の引用)表
指標 値(ns) 何を表すか
mean 70.1 合計を件数で割った値
中央値 83.0 真ん中の1回(刻みで丸め)
最大 19208 跳ねた1回

性能の報告と計算量の議論。別の話に見えますが、共通する構造は何でしょうか。

どちらも、ならした1つの数字と、最も伸びた1回との距離に注目してください。

この章のまとめ

  • 平均は計算で作る値なので、実在の1回と一致する保証がない。本教材の測定環境の640件では、平均 395.820 ms に一致する回が無かった。
  • パーセンタイルは順序統計量で、並べて何本目かを選ぶ。だから必ず実在の1回を指す。
  • 平均が無意味なのではない。 合計を戻せるのは平均だけで、容量計画・課金では平均が正しい道具になる。SRE Book も「generally prefer」と書くにとどめ、同じ本で平均レイテンシを SLO の例に使っている。
  • 平均と中央値の大小は分布の形で決まる。 本教材の640件の実測では、平均のほうが小さかった。
  • p99 が数えているのはリクエストであって利用者ではない。 1画面が複数のサービスに依存するなら、あるバックエンドの99パーセンタイルがフロントエンドの中央値になりうる、と SRE Book は書いている。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 4正解: 0

パーセンタイルが「必ず実在の観測値を指す」と言えるのはなぜですか。

用語集(4語)
平均(算術平均)
合計を件数で割った値。件数を掛ければ合計が戻るが、観測値のどれかと一致する保証は無い。
パーセンタイル
観測値を並べて、下から何%の位置にあるかで選ぶ値。順序統計量なので、選ばれるのは実在の観測値である(nearest-rank 法の場合)。
p50 / 中央値
小さいほうから数えて真ん中の値。Google SRE Book は、典型的な場合を強調する指標だとしている。
p99
下から99%の位置の値。リクエストを並べて数えた値であって、利用者を並べた値ではない。