1
/
5

アプリケーションエンジニアが初めて負荷試験やってみた

はじめまして、エンジニアの矢田です。

昨年の7月にクラシコムに入社し、SREチームでインフラの課題を解決したり、アプリケーション周りの機能実装を行ったりしています。

前職では短期間で様々なプロジェクトに参加し技術的な課題解決を行うというお仕事をしておりましたが、より身近な生活や人たちと関われるサービスで課題解決をやってみたいと感じたため転職しクラシコムにジョインしました。

残業がないので18時に退勤しビールが飲める最高の生活をしています。

今まではアプリケーションの開発のみでしたが、入社して初めてのプロジェクトはサービスの負荷試験でした。
この記事ではその負荷試験でやったことについて紹介させていただければと思います。


目的

クラシコムが運営する「北欧、暮らしの道具店」では様々な商品や読みものを取り扱っております。その中で、お客様が快適に安定して当店を利用できるように運用していく必要があります。


北欧、暮らしの道具店
北欧をはじめとする様々な国で作られたインテリア雑貨や、オリジナル商品ブランドのアイテムなどを取り揃えています。暮らしににまつわるコンテンツも日々お届けしています。
http://hokuohkurashi.com/


以前アプリのPUSH通知を配信した際にサービスが安定して提供できないことがあったり、人気の再入荷商品へのリクエストが捌けないことがあったりしました。

そのとき技術支援をしてくださっている面白法人カヤックさんから、負荷試験をしてみてはどうかという提案をいただき、まとまった時間をとって負荷試験を実施することになりました。

下記が具体的な目的です。

- 現状のシステムの処理能力の把握・性能改善
- 中・長期的なトラフィック増加計画に対するシステムの対応計画
- スケール性能(*1)の確認
- クラシコム内で継続的に負荷試験ができるようになる
(*1 インフラを増強したときに増強した分性能が上がるかどうかを確かめること)

「北欧、暮らしの道具店」はAWS上のインスタンスでいくつかのサービスに分かれて動いています。この記事ではその中でも主要なカート・決済ページ部分の負荷試験について説明しようと思います。

「北欧、暮らしの道具店」の現状

現在皆様に見ていただいている、「北欧、暮らしの道具店」のトラフィックは負荷試験を行った2020年7月時点でおおよそ下記です。

DAU: 3万ユーザ/Day
WEB(PC/SP): ピーク時 平均約250rps, 平均レイテンシ 約100ms
iOS/Androidアプリ用API: ピーク時 平均約45rps, 平均レイテンシ 約135ms

手順

負荷試験は下記手順で行います。

1. シナリオの作成
2. シナリオの実装
3. 負荷試験環境の作成
4. 負荷試験の実行

まず、実際のページへのリクエストに基づいてどのように負荷をかけるかのシナリオを作成します。それから、その作成したシナリオを実現できるように実装を行います。

実際に負荷をかける試験環境を、本番稼働しているページにできるだけ近くなるように作成します。このとき万が一本番に影響が出ないように、ネットワークを分けておきます。

シナリオの作成

カート・決済ページの負荷試験はお客様が商品をカートにいれて購入される流れを再現し観測したいので、ログを元にシナリオを作成します。

例えば、「(1)カートに商品をいれて」「(2)カートから購入ボタンをおし」「(3)配送先などを入力して」「(4)購入ボタンをおす」といった感じです。


具体的には、50%のお客様が商品ページを閲覧された時、そのうちの2%のお客様が商品をカートにいれ、さらに0.2%の確率で購入されるフローで回遊されます。こういった行動フローをアクセスログなどから作成しました。

シナリオの実装

先ほどシナリオの作成で挙げたフローを負荷試験ツールで実現します。
今回の負荷試験では複雑なシナリオを実現する必要があったため、k6というツールを選定しました。

k6ではjavascriptで負荷をどのようにかけるかを実装できるので、複雑なシナリオを実現できます。また、Go言語で実装されているため負荷試験ツール自体がボトルネックになってしまう恐れが少なくたくさんの負荷を対象にかけることができます。

測定周りの設定

k6では負荷試験をCLIで実行し、結果もCLIに表示されます。最初はコピーアンドペーストで記録していたのですが、大変だったためshellscriptで結果を整形しSlackに通知するようにしました。

また、CPU使用率やメモリ使用量などの外形監視にはMackerelを利用し、コード内部のパフォーマンス解析をするためにDatadogも利用しました。

クラシコムではもともと業務でメトリクス収集や監視にMackerelを使っていたので、今回も外形監視に利用しましたが、負荷試験時にAPMを利用したかったためAmazon X-RAYなど他のAPMと比較し、コスト・導入しやすさなどの観点からDatadogを新規に導入しました。

Datadogは負荷対象のインスタンスの内一台のみにインストールし計測を行いました。

環境の作成

負荷試験を行う環境は下記の図のように作成しました。

今回説明するカート・決済ページの試験ではEC2とAuroraに依存しています。(Elasticsearchも利用していますが、今回のシナリオではリクエストが行っていません。)


AWSのアカウントはステージング環境と同じですが、他環境からアクセスができないようにInternal ALBを利用し、他環境へ影響が出ないように別のVPC内で作成しました。

負荷試験の実施

負荷試験を行うための環境や実装が終わったら実際に負荷をかけていく作業に入ります。

まず、どの程度の負荷をかけるのか、捌いて欲しいのかの目標値を設定します。
今回は

スループット*2: 2500~5000rps レイテンシ*3: 100ms程度

としました。
*2: 一定時間内に処理できるデータ量のことで、負荷試験では単位は1秒間に処理されたリクエスト数を表す、rpsがよく使われる。大きい方が嬉しい。
*3: データの転送要求を出してからその結果が返されるまでの時間のこと。小さい方が嬉しい。

実際に負荷をかける際は並列数*4と負荷をかける時間を指定します。

負荷をかける時間は5分間で固定し、並列数をどんどん増やして行ってスループットやレイテンシ、そのほかのメトリクスを確認します。
*4: 一度に並列でリクエストをかける数

この負荷試験は、SREチームとカヤックさんとでGoogle meetを繋ぎ(在宅勤務をしているので)、画面共有しながら実施しました。

画面共有ではMackerelでメトリクスを見たり負荷をかける対象のサーバーに入ってdstatコマンド*5でCPU使用率の動きを見たりしながら、「負荷ちゃんとかかってる」とか「Elasticsearchそろそろ詰まるかも」とかやいのやいの言いながらやっていました。

不審なメトリクスの動きがあったときは、カヤックさんに調査する箇所のアドバイスをいただきながら、ログを見たり設定を確認したりし、原因を調査しました。

*5
$ dstat -t -a

結果

カート・決済ページは下記の構成で負荷をかけて行きました。

(1) EC2: c5.xlarge x 2台, Aurora: db.r5.xlarge
並列数 8, 16, 24
(2) EC2: c5.xlarge x 2台, Aurora: db.r5.xlarge
並列数 16, 32, 64
(3) EC2: c5.xlarge x 4台, Aurora: db.r5.2xlarge
並列数32, 64, 128

構成(1)では32並列の時、構成(2)では64並列のときにCPU使用率が80%を超え、これ以上性能がでないことがわかりました。

並列数を増やしていった上でCPU使用率も比例して伸びており、80%まで使い切れているのでスケール性能があることが確認できました。
また、目標のスループット・レイテンシも出ていることが確認できました。


構成(1)では32並列の時、構成(2)では64並列のときにCPU使用率が80%を超え、これ以上性能がでないことがわかりました。

並列数を増やしていった上でCPU使用率も比例して伸びており、80%まで使い切れているのでスケール性能があることが確認できました。
また、目標のスループット・レイテンシも出ていることが確認できました。


(注) 画像の値は試験中の値で、CPUが使い切れた時の値ではありません。

負荷試験の結果より修正した箇所

負荷試験の結果を受けて、カート・決済ページではEC2のインスタンスタイプとインスタンス数の変更を行いました。

また、カート・決済ページではスケール性能が確認できたのでアプリケーション内の変更は行いませんでした。

変更ではインスタンスタイプを大きくしインスタンス数を減らしたのですが、このことによってパフォーマンスがよくなるだけでなく管理するインスタンスを減らすことができました。

今回説明した範囲ではないのですが、コンテナのメモリ数を調整したりElasticsearchへの接続方法をhttpsからhttpにしたりなどのインスタンスタイプ以外の変更を行っている箇所もあります。

感想

私は今まで負荷試験を何ヶ月もかけて行ったことがありませんでした。

社内のソースコードやアーキテクチャもあまり詳しくないまま始まりましたが、負荷試験では実際によく触られるフローに沿ってシナリオを実装するのでサービスの全体感が負荷試験を通して掴むことができました。

試験中のメトリクスの見方がなかなか初心者には難しかったですが、カヤックさんがリードしてくださったので負荷試験のやり方から結果の見方までとても勉強になりました。

また、最初に負荷試験をプロジェクトとしてやるというお話を聞いたときに、機能開発やバグ修正でなく、言ってしまえばお金に直接関わらない箇所に10人もいないチームでそんなに時間も人も使っていいの?!と驚きました

しかも、負荷試験用の環境を作ったりDatadogを導入したりしてお金がかかったのですが、それもすんなり承諾を得られていたのも驚きでした。

負荷試験のプロジェクト以外もですが、クラシコムでは納期や期日よりもクオリティを優先させてくれる風潮にあります。短期的ではなく長期的な目線で本当に必要かどうかを判断し、必要なところにはお金も時間も人間もかけて良いという判断がうまいなあと個人的に感じています。

こういったところが、会社のメンバーや「北欧、暮らしの道具店」、他のプロダクトやお客様に伝わって、またクラシコムに返ってきて良いプロダクトやプロダクトの空気感につながっているのかなと思いました。

こんなふうに、新しい領域にチャレンジすることに興味を持ってくださる方がいらっしゃったら、ぜひ声をかけてください。


株式会社クラシコムでは一緒に働く仲間を募集しています
3 いいね!
3 いいね!

同じタグの記事

今週のランキング