ホーム 職種別 エンジニア Locust x Fargateで10000RPS越えの負荷試験をした話
Locust x Fargateで10000RPS越えの負荷試験をした話
 

Locust x Fargateで10000RPS越えの負荷試験をした話

コンテンツデザイン部の金井と申します。今回はLocustとFargateを使ってゲームアプリケーションの負荷試験をした話をしていこうと思います。

背景

結構前の話になりますが、自分はとあるゲームアプリケーションの開発・運営に携わっていました。
開発・運営に携わると言う事は、リリースにも携わるという事で、その点において自分は負荷試験を主に担当していました。

負荷試験ツールに何故Locustを使ったのか

負荷試験に関しては、別のプロジェクトから引き継いだサーバーソースではJMeterを使っていたのですが、JMeterは

  • 専用のGUIでの負荷試験シナリオ作成がややこしく、学習コストも高い事
  • 保存されるソースがXML形式であり、gitでのバージョン管理に向かない事
  • 負荷試験を行う際も面倒臭い点が多い事

という難点が他にも色々あるのに対し、Locustは

  • コードベースでの負荷試験シナリオ作成であり、学習コストは低く、またそれ故にgitでのバージョン管理に向く
  • 負荷試験の実行がJMeterに比べると単純で分かり易い

とメリットが多く、また他プロジェクトでも使用実績があった為、Locustに乗り換える事にしました(そして100近いAPIの負荷試験シナリオを1から書き直す事になりました)。

Locustは日本語でイナゴです。サーバーに蝗害を起こしにいくイメージですね

負荷試験サーバーに何故Fargateを使ったのか

そもそもFargateが何なのかを説明すると、AWSにおける、コンテナ向けのサーバーレスコンピューティングリソースです。
実態の無いサーバー、とでも言えばいいでしょうか。
実態……ホストマシンの存在が隠されている為、IPアドレスをこちらで決められなかったり、EC2のようにssh接続して中身を見たりする事は基本出来ない(方法が無い訳では無いみたいだけど)という欠点がありますが、
コンテナベースで立ち上げる為、OSなどを考慮する必要もなく、より手軽な使い方が可能です。
また負荷試験に対しては、インスタンスの増減に必要な設定がEC2よりも少なく、容易であるという点より、

  • 負荷試験の規模に関わらず準備の手間が殆ど変わらない
  • コストも鑑みて頻繁に起動と削除を繰り返す必要がある為、手軽であるのは強い

というメリットがありました。
それに元々サーバーインフラはAWSで立てていましたし。

負荷掛け環境構築まで

ネット上に先駆者が沢山居ましたので、そこ辺りで色々調べていけば、そこまで苦労する事は……一つだけありましたね。
AWSのPowerUserAccess権限ではECSでのタスク定義やクラスター定義の作成、編集が出来ないという点です。
務め人で、しっかり権限が個々に割り当てられているからこそ起きる問題ですね。最小権限の原則ってヤツです。
そして、AWSはそういう時にコンソール上で、これこれこういう理由で作成出来ませんでしたって通知してくれない場合が多くて(セキュリティ上の都合もあるんでしょうけど)、もっと上の権限を割り当てられていた先輩に聞いてみたら、俺は出来るけど? 何かミスってない? と返されたりして。
同じ画面で全く同じ操作をして自分だけ出来ないと証明して、やーっと気付きました。
コロナでリモート勤務だったのもあって、1~2日は潰した気がする。

GithubやSentryも権限がない状態でリポジトリやらプロジェクトやら開こうすると、冷徹に404返して来るしなぁ

負荷掛けられサーバー環境構築まで

プランナーに本番想定のマスタデータを貰って、それを本番に寄せた開発環境の1環境に反映しておしまいです。
また本番に寄せたと言っても、負荷試験のシナリオの都合上、例えば以下の点で異なってくる部分なども出てくるので、そういうのはきちんと纏めておきましょう。

  • 通信の暗号化は本番と同等か?
  • ミドルウェアはきちんと全て動作させる仕組みになっているか(BigQueryなどにデータを入れるところまできちんと出来るようにしてるか)?
  • 課金処理は途中で飛ばしたりしていないか?

そうでないと、後で痛い目を見る事になったりします。

後、ちゃんと監視ツールも設定しましょう。
NewRelic, Datadogやら, それからAWSを使っているのならばCloudWatchで、APIサーバー、それからDBやMemcachedなど各種ミドルウェアのCPU使用率、メモリ使用率、その他諸々を可視化出来るようにしておきましょう。

本番想定の負荷試験を実行するまで

いきなり本番想定で流す、という事はしません。ちゃんと、API全般が基本問題ないかを確認した上で、想定される本番と状況を出来るだけ近付けてやります。

小規模に全てのAPIを流すシナリオを動かして重いAPIがないかを確認する

ここで重いAPIがあった場合は、根本的にソースが重いのでちゃんと直しましょう。

リセマラを想定したシナリオを動かして問題ないかを確認する

要するに、リリース直後にチュートリアル周りを何度も重点的に走らされても問題ないか、という確認ですね。
後、本番想定にする為にDBにユーザーデータを蓄えないといけないのですが、
スクリプトを組んでユーザーデータを大量生産するとかも手としてはありますが、リセマラのシナリオを長時間流していればそれと同等の代物が出来上がって来るので、その方が調査も兼ねられて良いのではないかと思います。

中規模に全てのAPIを流すシナリオを動かして重いAPIがないかを確認する

ユーザーデータが作られた後に、再び全てのAPIを通る負荷試験を流してみましょう。
ここで重いAPIがあった場合は、DBのインデックスが正常に張られてないのが主な原因です。ちゃんと張り直しましょう。

ここまでやれば、サーバーソースの基本的な部分に関しては問題ないと言えるでしょう。

このタイミングで仕様変更ですか!!??!!??

本番想定の負荷試験

ここまでやって、本番想定の負荷試験を行います。
本番想定の負荷を掛けても問題ないか、という他に、

  • 長時間に渡って負荷を掛け続けて問題ないか
  • 本番想定以上の負荷を掛けてサーバーは落ちないか(DBなどの拡張が簡単に効かないミドルウェアの性能限界はどこか?)
    唐突に急激なリクエスト数が来てもサーバーは落ちないか(AutoScalingは効いてくれるか?)
  • デプロイなどを挟んでもサーバーは正常に動くか

といった事等を調べていきます。
本番で起こり得るような事象を前もって列挙し、それらに対して問題ないか、また、この構成の限界はどこにあるのか、そういう点を調査していく訳ですね。

ここまで来たら負荷試験のソースもしっかり整ってますし、後はリクエスト数を変えたりして動かしていくだけなので、負荷試験を行う事自体には苦労はしないでしょう。
ただ……ここからで何か起きたりした場合は、苦労する事になりがちです。
原因がイマイチ見えにくいところにあったり、どこも正常なはずなのに動いてくれなかったり、エラーレートが唐突に爆上がりしたり……。
粘り強くやっていきましょう。はい。それしかないです。

おじいちゃん、AWSでmemcachedのクラスターエンドポイントを指定しちゃうと、キーが一緒でも参照するたびにクラスターの中の別のホストを見てしまうんですよ

そして、10000RPSの負荷試験は、本番想定以上の負荷を掛けてサーバーは落ちないかという負荷試験で達成しました。

え? そんな負荷掛けて、どれだけのクラウド料金が掛かったのかって?
うーん……自分の給料の半年分くらいかなあ。
ちゃんと負荷試験やってない時はこまめにサーバー落としたりしても、その位行っちゃいましたね。
まあ、その甲斐あって、リリース後にサーバーが落ちたりする事はなく、何秒も掛かるようなAPIは……ちょっと出てきちゃったけど、即刻メンテに入れなければいけないレベルではなかったです。

記事を共有

最近人気な記事