ゲームラグ白書 › 一部のユーザーだけに起きる問題
特定キャラクターのデータ肥大化 One character with oversized data (inventory, mail, buffs)
原因ID pt-heavy-char · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
図と実験のあるメインページでこのカードを開く →
アイテム・郵便が数千個たまっていたり、フレンド・ブロックリストやバフが極端に多かったりするキャラクターは、接続時・保存時・周囲への通知で扱う量がほかの人の数倍になります。回線に関係なく、そのキャラクターでだけ重くなります。
なぜ 長く育てたキャラクターやイベント報酬で、インベントリ・郵便受けに数千個たまる → すると 接続・エリア移動・保存のたびにその分DBを読み書きし、周囲に送る装備・バフの情報も大きい → 画面では そのキャラクターだけ入場時のロードが長く、インベントリ・郵便を開くときに一瞬止まる。保存をゲームスレッドで待つサーバーなら、周囲の人まで一時的に止まる
- 症状
- 接続不可・無限ロード, 入力遅延, フリーズ
- 要因
- ストール
- 誰に起きるか
- 自分だけ, 特定の機能だけ
- いつ
- 接続直後・メンテ明け, 特定の操作をしたとき, 移動中・マップ切り替え時
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
- ゲーム開発チームの対応
- インベントリ・郵便の保管上限と古い郵便の自動整理、必要な部分だけを分けて読み込む、保存は変わった部分だけをゲームスレッドの外で。
- インフラチームの対応
- スロークエリログから同じキャラクターで繰り返される遅いクエリを見つけてゲーム開発チームに伝える、アイテム・郵便の行数が多いキャラクターの上位リストを提供。
- 数値の目安
- アイテム1個がDBの1行なら、アイテム5,000個のキャラクターは接続のたびに5,000行を読みます。ふつうのキャラクターの数十倍です。
- グラフでは
- 一部だけ高い · キャラクターごとの接続・保存時間、キャラクターごとのDB読み取り行数
- 確認箇所
- DBのスロークエリログ(MySQL slow query log、PostgreSQL log_min_duration_statement)で同じキャラクターIDで繰り返される遅い読み取り・保存を探し、アイテム・郵便テーブルのキャラクターごとの行数の上位リストを抽出
- 該当する場合
- スロークエリが一部のキャラクターIDに集中し、そのキャラクターのアイテム・郵便の行数が平均の数十倍で、別のPC・回線から接続しても同じように遅い
- 該当しない場合
- 同じアカウントの別キャラクターやほかのユーザーも一緒に遅いなら、DBサーバー・ロック側。そのキャラクターが別のPCでは問題ないなら、ユーザーの環境
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- 同じキャラクターで別のPC・回線から接続しても同じように重く、同じアカウントの別キャラクターは問題ないなら、キャラクターデータを疑います。報告にキャラクター名が欠かせない理由です。
出典
- Extraneous Fetching antipattern Microsoft Azure
必要以上のデータを取得するとI/O負荷が増え、応答が遅くなる - PostgreSQL Documentation: Error Reporting and Logging PostgreSQL
log_min_duration_statement:一定時間以上かかったSQLを記録し、スロークエリを追跡 - The Slow Query Log MySQL
long_query_timeを超えたクエリを記録するスロークエリログ
あわせて読みたい原因
同じ層:一部のユーザーだけに起きる問題
同じ症状(接続不可・無限ロード)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る