ゲームラグ白書 › L12 データベース
コネクションプールの枯渇 Connection pool exhaustion
原因ID db-pool · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
図と実験のあるメインページでこのカードを開く →
DBとの接続数は決まっているため、遅いクエリが接続を占有すると、残りの要求は待たされます。
なぜ 遅いクエリや要求の殺到で、すべての接続が使用中 → すると 新しい要求は接続が空くまで待つ → 画面では ログインの無限ロード、保存の遅延、タイムアウト
- 症状
- 接続不可・無限ロード, 入力遅延
- 要因
- ストール, 遅延
- 誰に起きるか
- サーバー全体, 特定の機能だけ
- いつ
- 接続直後・メンテ明け, 人が集中したとき
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
- ゲーム開発チームの対応
- 遅いクエリの排除、プールサイズと待ちタイムアウトの調整(プールをむやみに大きくしない)、機能別のプール分離。
- インフラチームの対応
- DBの最大接続数とCPU・IOPSの余裕を確認、増設・オートスケーリングの前にサーバー台数 × プールサイズが最大接続数以内か確認、コネクション待ち・ロック待ちのメトリクスを監視に追加。
- 数値の目安
- 必要な接続数は「毎秒の要求数 × 1件が接続を占有する時間」で見積もります。1秒に2,000件、1件あたり5msなら、平均10本が常に使用中です。集中するときに備えて、通常はその2〜3倍を用意します。クエリが150msに遅くなると、同じ要求数で300本が必要になります。
- グラフでは
- 上限で頭打ち · 使用中のDB接続数、コネクション待ち時間
- 確認箇所
- DB側でゲームサーバーごとの接続状態を集計。MySQLはSHOW PROCESSLISTのHost・Command(アイドル状態の接続はSleep)・TimeとThreads_connected・Threads_running、拒否された接続数Connection_errors_max_connectionsを確認。PostgreSQLはpg_stat_activityをclient_addr・stateでまとめて集計。ゲームサーバーのコネクションプールライブラリが待ち数・待ち時間を出力していれば、合わせて確認
- 該当する場合
- 1台のゲームサーバーの接続がプールサイズいっぱいまですべてクエリ実行中で、アイドル状態の接続が0の間、ログイン・保存が待たされる。またはDB全体の接続数がmax_connectionsに達し、新しい接続が拒否される
- 該当しない場合
- アイドル状態の接続が十分あるのに遅いなら、クエリ自体の遅延(db-no-index、db-hot-row)かDBリソースの飽和側
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- プールをむやみに大きくすると、DBのCPUとロック競合が増えるだけで、全員が一緒に遅くなります。また、サーバー台数 × プールサイズがDBの最大接続数を超えると、増設したサーバーや再起動したサーバーが接続すら確立できません。オートスケーリングやメンテ明けによく起きます。
出典
- Number Of Database Connections PostgreSQL
DBのリソースを使い切った後は、接続を増やしてもスループットがかえって落ちる、アクティブな接続をリソースに合わせて残りはキューで待たせるほうが、遅延・スループットともに良い - Too many connections MySQL
max_connectionsを使い切ると、新しい接続はToo many connectionsエラーで拒否される - Connections and Authentication (PostgreSQL Documentation) PostgreSQL
max_connections:同時接続数の上限、デフォルトは通常100 - SHOW PROCESSLIST Statement MySQL
Host(クライアントのアドレス)、Command(アイドル状態のセッションはSleep)、Time、State - Server Status Variables MySQL
Threads_connected・Threads_running、Connection_errors_max_connections(max_connectionsに達して拒否された接続数) - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity:接続ごとのclient_addrとstate(active、idle、idle in transactionなど)
あわせて読みたい原因
同じ層:L12 データベース
同じ症状(接続不可・無限ロード)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る