サーバーの平均負荷は低いのに遅い:混雑と待ち時間の調べ方
サーバーの平均CPU使用率は低いのに、昼休み明けだけ画面が遅い。平均値から増設を決める前に、その時間に何件が届き、どこで待ったのかを見たいところです。同じ平均負荷でも待ちが変わる仮定を入口に、到着の集中、重い処理、後段の詰まりを分けて考えます。
この記事の目次
平均負荷が同じ50%でも、待ちは違う
一件1分、担当一人、開始前の待ちはない条件を置く。一時間に30件を2分間隔で受ければ、各件は到着後すぐ開始できる。同じ30件が最初に一度に届くと、開始までの待ちは0、1、…、29分、平均14.5分、最後の完了は30分後になる。時間全体の処理負荷はどちらも50%だ。
これは到着列を固定した算術で、実際の処理の揺れを入れた待ち行列の推定ではない。Littleの関係を使う場合も、途中で溜まったものを除外しない観測区間と安定した平均が要る。増設の前に、平均の分母である一時間の中で到着がどう並んだかを確かめる。
利用者の操作から、結果が届くまでをたどる
この判断で比べたいのは「機械を増やすか否か」だけではない。ピークの到着を分散する、重要な依頼を優先する、重い処理を後へ回す、処理能力を増やす、という選択肢である。まず利用者の操作を起点に、到着から結果が届くまでの時間を分けて読む。
能力不足と、一時的な混雑を分ける
平均使用率は観測期間の取り方に左右される。24時間平均が低くても、業務開始時の15分は処理能力を超えているかもしれない。逆にピーク時のCPUが高くても、利用者が待つ原因は別のデータベース接続や外部APIにある場合がある。そこで時間帯、依頼種別、利用者群、成功・失敗を同じ粒度で結び、待機時間と実処理時間を分離する。利用率だけを増設の発注書にしてはいけない。
Google SREの連鎖障害の章は、リクエストをキューにためすぎると、後で処理できたとしても待ち時間が増え、呼び出し元の期限切れや再試行が負荷を増やす過程を説明する。同章は安定した負荷なら短いキューが有効なことがある一方、突発的な負荷にはバーストの大きさと処理時間を考慮したキューが必要とも述べる。「キューは短ければ必ず良い」という単純な話ではない。
待ちを考える補助線には、Littleの待ち行列に関する原論文がある。安定した系では平均の滞留件数、到着率、滞留時間が関係する。ただし、この関係から「CPUを何台増やせば何秒縮む」という効果は直接導けない。ピーク中に到着が処理を上回り続ける系を、安定した平均の式だけで評価してはならない。
到着・重い処理・能力不足のどこで詰まるか
第一の仮説は、短時間に到着が集中していること。これは「平日の平均」ではなく、利用者が遅いと訴えた数分の到着件数と完了件数を並べれば検討できる。受付の直後から待っているなら、予定処理の時刻をずらす、入力を小分けにする、同期で返す必要のない仕事を後へ移す案がある。仕事をずらしても総量が変わらず、別の時間へ混雑を移すだけなら効果は限定的だ。
第二の仮説は、少数の重い依頼が資源を占有すること。平均処理時間とともに、遅い側の依頼の内訳を見る。巨大な帳票を作る一件と短い検索を同じ待機列に並べれば、検索の利用者が理不尽に待つ。列を分ける案は有効かもしれないが、共有データベースの負荷が同じなら列だけ分けても解決しない。実行先の資源まで追う必要がある。
第三の仮説は、能力そのものが足りないこと。混雑時に処理点が継続して飽和し、依頼の量を変えずに処理能力を増やす試験で完了数が増えるなら、増設を選ぶ根拠が強まる。ただしアクセスの失敗が減った反面、請求の後工程に未処理が積み上がるなら、改善したのは一部だけだ。設備費には運用費や故障時の切替も含め、成果は利用者の完了で確かめる。
仮想の月末業務なら、どの案を選ぶか
以下は実測値ではない。月末に帳票作成依頼が同時に増え、普段の検索も遅くなる職場を想定する。帳票が夜までに終わればよく、検索はその場で必要なら、帳票を非同期の列へ移し、検索の待ち時間を守る案が先に来る。機械を増やしても、帳票が同じデータベースの重い集計を同時に走らせる限り、ボトルネックが移るだけかもしれない。
条件を変えよう。帳票自体が朝の締めまでに必要で、既に待機列を分け、遅い処理も最適化した。それでもピークの到着が持続し、増設した試験環境で依頼の完了数が増え、下流の待ちが悪化しない。この場合は設備追加が合理的になる。逆に一部の部署だけ遅いなら、全社増設の前に部署固有の入力やネットワーク経路を確かめたい。例は方針を逆転させる条件の説明であり、架空の数値を実績に見せるものではない。
先に拒否する判断も、利用者の仕事を守るため
「全部受け付けて順番に処理する」は公平に見える。しかし待っている間に利用者の画面が時間切れになり、同じ操作が再送されるなら、遅れて成功する処理に資源を使いながら新しい依頼をさらに待たせる。重要度の低い要求を早く断る、呼び出し元に再試行の間隔と上限を設ける、期限が切れた仕事を下流へ流さない、という方法がある。これは仕事を捨てる提案ではなく、処理できない約束を積み上げない設計である。
Google SREの過負荷対処はCPUだけでなく実行待ちスレッドなど局所の信号を使い、重要度に応じて拒否を変える事例を記す。ただしGoogleの通信基盤と負荷分散の前提がある。利用者が再送できない申請、法定期限にかかわる取引などに、そのまま「拒否すればよい」とは言えない。受け付けを止めるなら、受付済みを失わない記録、再開通知、再送時の重複防止も設計に入る。
対策後も、結果が使える時刻まで見る
性能のグラフは、同じ時間軸に置かなければ原因を示さない。昼のCPU使用率と夜の問い合わせ件数を並べても関係は分からない。負荷試験の結果も、本番と依頼の大きさやキャッシュの状態が違えば外挿できない。平均、遅い側の分布、失敗、期限切れを時間帯と依頼種別ごとに見る。利用者が操作を諦めた件数はサーバーの成功件数から消えるため、フロント画面と問い合わせも手掛かりになる。
過負荷時の拒否率だけを下げるのも危険だ。受付を再開しても、回答が使える時刻を過ぎていれば利用者の目的は達していない。逆に低重要度の夜間集計を遅らせても、翌朝の期限に間に合えば損失は小さい。優先度は技術の都合ではなく、仕事の期限と失敗時の代替手段で決める。これは実務上の判断手順であり、Googleの事例から一律の閾値を輸入したものではない。
混雑を移す案を採るなら、移した先の時間に利用者や担当者がいるかも確認する。夜間処理に変えた結果、翌朝に失敗が見つかって手直しが集中するなら、問題を先送りしただけだ。処理が終わった時刻ではなく、担当者が結果を確認して次の仕事を始められた時刻まで追いたい。
夜間への移動や優先順位の変更は、利用者間で負担を移す可能性がある。急がない仕事を待たせるときも、受付済みの依頼が消えないか、いつ終わる見込みかを示す。結果が使える時刻と、遅れる仕事の持ち主を明らかにして初めて、容量対策を業務判断として説明できる。
「改善した」は何で確かめるか
変更案を試したら、混雑した時間帯の到着件数と、依頼から完了までの待ちを比較する。仕事の種類や到着の集中度が変わった場合は、機械の平均負荷だけで改善を判定しない。到着をならして待ちが減るなら流し方の問題、集中が続き処理能力を超えるなら増設の問題として、先に挙げた三つの仮説へ結果を戻す。