リアルタイム音声AIの負荷分散を、Web APIと同じQPS(1秒あたりのリクエスト数)だけで設計すると危険です。短い100件より、20分続く5会話のほうが重いことがあるからです。Google Developers Blogは2026年8月、CPU使用率に「アクティブなセッション数」を重ねる設計を紹介しました。重要なのは、いま使っている資源だけでなく、すでに引き受けた仕事も測ることです。
QPSとCPUだけでは見えない負荷
通常のAPIは、要求を受けて応答すれば処理が終わります。一方、音声・動画などのリアルタイムAIは、WebSocketやgRPCの双方向ストリームを長時間維持します。その間、音声バッファ、途中の文字起こし、モデルの文脈、ツール呼び出しなどがランタイム内に残ります。
ここで2つの錯覚が生まれます。
- QPSの錯覚:新規接続が少なくても、長時間セッションが積み上がっている可能性があります。
- CPUの錯覚:利用者が黙っている間は低負荷でも、同時に話し始めれば一気に処理が集中します。
Googleの記事は、CPUを「現在の圧力」、アクティブセッション数を「将来分も含む約束済み負荷」と捉えています。片方を捨てるのではなく、両方を見るのがポイントです。
設計は3つの信号を分ける
リアルタイムAIでは、少なくとも次の3信号を別々に観測します。
- 到着量:新規セッションの開始率
- 現在負荷:CPU、メモリ、推論待ち時間
- 約束済み負荷:各バックエンドが保持するアクティブセッション数
単純な空き枠は「最大セッション数 − 現在のセッション数」で表せます。ただし、全セッションの重さが同じとは限りません。実運用ではCPUやメモリと組み合わせ、安全係数を置いて新規割り当てを徐々に増やします。見かけ上アイドルな1台へ接続を一気に流し込まないためです。
実装で外せない4点
- 開始と終了をアプリ内で数える
ロードバランサーからは、会話中・待機中・ヘルスチェックの区別がつきません。セッションの意味を知るランタイム側で計測します。 - 必ず終了処理を通す
正常終了だけでなく、タイムアウト、キャンセル、切断でもカウンターを戻します。残った「幽霊セッション」は、メモリリークだけでなく誤ったルーティング判断を生みます。 - 二重減算を防ぐ
切断とタイムアウトが同時に発火しても、終了処理は一度だけにします。実際より空いているように見せる誤カウントのほうが危険です。 - 観測窓と安全係数を決める
瞬間値で振り回されないようCPUを平滑化し、メトリクス取得間隔の遅れも見込んで保守的に割り当てます。
負荷試験も「短い大量リクエスト」から変える
短い要求を連打する試験だけでは、リアルタイムAIの故障モードを再現できません。Googleの記事は、同時セッション数、継続時間、到着パターン、無音と発話の比率、キャンセル・切断率、バックエンド数などを変えるよう勧めています。
確認したい指標も平均応答時間だけではありません。
- バックエンド間のアクティブセッション分布
- 過負荷なインスタンスへ割り当てた比率
- 起動レイテンシのp95・p99(遅い側から数えて上位5%・1%に当たる値)と最初のストリームまでの時間
- 切断後にカウンターが正しく戻るか
- セッション切断数
さらに、共有カウンター自体もクリティカルパスです。高並列時には単一のアトミックカウンターが競合点になり得るため、単スレッドの速さではなく競合時の挙動を測ります。
プロジェクトリーダー視点では「処理量」より「引受残」を管理する
これはプロジェクト管理にも似ています。今日届いた依頼件数だけでは、チームの余力は分かりません。すでに着手し、完了責任を負っている案件の残量も必要です。
リアルタイムAIでも、QPSは入口、CPUは現在、セッション数は引受残です。この3つを分離して見れば、オートスケールの判断、ルーティング、SLO(サービス品質目標)の原因分析を同じ枠組みで議論できます。ネットワーク設定だけで解こうとせず、アプリケーションの状態をインフラへ安全に渡す設計が必要です。
まとめ
- 長時間ストリームでは、QPSだけではバックエンドの忙しさを測れません。
- CPUは現在負荷、アクティブセッション数は約束済み負荷として併用します。
- 終了漏れと二重減算を防ぎ、現実的な会話パターンで負荷試験します。
- リアルタイムAIの負荷分散は、接続数ではなく「生きた会話」を配る設計です。
