スマフォゲームアプリの負荷試験いろは

スマフォゲームアプリの負荷試験をしたので、どのように実施したのか共有したいと思います。 今回はDAU10万人を想定して負荷試験を行いました。

使ったツール

  • 負荷試験クライアント
  • 性能監視
    • New Relic (通常の監視に加え、MySQL Pluginを入れるといい)
    • AWSの標準のモニタ

単純な構成で負荷試験

まず疎通確認の意味も込めて、単純な構成で負荷試験を行います。 今回は、渡されたjsonをechoするだけのAPIを作って、locustを使い負荷試験を実施しました。 いきなり複数台で行うと、パフォーマンスが出なかったときに、どこを調整していいかわからなくなります。 まずAppサーバ自体でDjangoフレームワークがどのくらいパフォーマンスが出せるのか確認します。 (本来だったら、素のDjangoでやるのがいいのですが、今回は開発しているアプリサーバのDjangoAPIを足す形にしてあります)

server_1.png

結果として、DjangoのAppサーバが70%ほどのCPU使用率で、600RPSほど捌けました。 Django自体のベンチマークと比較したりして極端に遅くなっていないかなど見直すといいと思います。

またこの試験を行う利点として、負荷クライアントのlocust自体も性能を発揮できるか確認できます。

単純な構成でうまくいったら、次にテストシナリオを作成します。

テストを行うユーザの定義とテストシナリオ作成

負荷試験を行う際に、想定されるユーザの定義と、達成すべき目標を決めます。

アプリの特性にもよると思いますが、今回はユーザを以下のように、 ヘビーユーザ , 一般ユーザ , 新規ユーザ として定義します。

  • ヘビーユーザ: ゲームにのめり込んで遊んでくれているユーザ
  • 一般ユーザ: ゲームを遊んだことがある既存ユーザだが軽めに遊ぶユーザ
  • 新規ユーザ: その日に、新しくゲームをインストールして遊んでくれるユーザ

DAU10万人を想定するといっても新規ユーザが多いのか、ヘビーユーザが多いのかによって、叩かれるAPIの数や種類が違い、負荷が全然違ってきます。 ヘビーユーザが多いとゲームのコアの部分、例えばクエストやPvPが多く遊ばれます。一方で、新規ユーザが多い場合、サインアップ後の登録処理のAPIが多く叩かれます。

ユーザを特徴的なセグメントにわけれたので、次にどのようなAPIがそれぞれ叩かれるのかを以下のように定義しました。

user_1.png

  1. 各セグメントが叩くAPIを定義する
  2. 各セグメントがそれぞれのAPIをどのくらい叩くか定義する
  3. 各セグメントの1ユーザが1日に叩くAPIの数を算出する (図だとヘビーユーザは340)
  4. 3に各セグメントのDAUをかけて、足しあわせ、システムにくる1日のリクエスト数を出す (図だと13,510,000)
  5. 4により平均RPSが算出できる
  6. いままでの経験値などからピーク値は3倍ほどと見積もり469RPS(Request per Seconds)をシステムが出す必要がある

上記のように定義したものを、実際にlocustでシナリオを作成し、負荷試験をしました。

シナリオを使って1台のサーバに負荷試験

いきなり複数台のAppサーバを使って負荷試験をせずに、1台だけでやります。狙いとしては、テストシナリオの疎通確認という意味と費用削減です。 いきなり複数台のAppサーバをたてると、エラーがあっていろいろ試行錯誤している間にもお金がかかりよくありません。 以下のような構成でMySQL, Redisも含めたテストシナリオの試験をします。

server_2.png

想定の負荷に耐えるように負荷試験

最後に、以下のようにサーバをセットアップし、目標であるRPSを達成できるまで負荷試験を実施します。 Appサーバの負荷が高く(CPUが70%以上など)なればAppサーバを増やすか、スペックをよくします。MySQL, Redisに関しても同様です。

server_3.png

まとめ

自分のプロジェクトでどのように負荷試験をしたか書いてきましたが以下がポイントでした。

  • 最小構成から大きくしていくこと
  • 想定ユーザからテストシナリオを作る