なぜサーバーレスで負荷試験が必要なのか
負荷試験とは、システムに擬似的な負荷をかけて処理能力を測定し、実運用に耐えられるかをリリース前に検証するテストです。大きく分けて以下の種類があります:
- 負荷(Load)テスト:想定される通常の負荷での性能検証
- ストレス(Stress)テスト:システムの限界を見つけるテスト
- スパイク(Spike)テスト:短時間で急激に負荷が増加する場合の検証
- 耐久(Endurance/Soak)テスト:長期間の稼働での安定性検証
それぞれのテストは目的が異なるため、検証したい項目に合わせて適切なテストを選択する必要があります。では、どのような目的でテストを行う必要があるのでしょうか。
1. コスト予測のため
サーバーレスのサービスの多くは、使った分だけ支払う従量課金制です。想定されるワークロードや実行時間に単価を掛け合わせれば、おおよその料金を推測できます。しかし、実際のシステム稼働時のワークロードや実行時間を事前に正確に見積もるのは意外と難しいもの。そこで構築時に負荷試験を行い、実際のコストを見積もる必要があります。
AWSでは、リソースに対してコスト配分タグ(Cost Allocation Tags)を設定でき、このタグによって実際に利用したリソースを分類することができます。これを利用することで、「このシステムは、このくらいの負荷がかかると、これくらいのコストになる」という実測値が得られます。AWS Cost Explorerからタグでフィルタリングすれば、1日や1ヶ月単位での費用を確認できます。

2. サービスクォータ引き上げの判断材料として
AWSを含むクラウドサービスには、デフォルトでさまざまな制限(サービスクォータ)が設けられています。例えば DynamoDBのリクエスト数や、Lambdaの同時実行数などです。こうした制限はAWSへ上限緩和申請をすることで引き上げられるものもあります。
実際に負荷をかけてみることで、どのサービスの、どの制限に引っかかるかが分かります。それを基に、サービスクォータの引き上げをどのサービスに対して行うべきか、どの程度の引き上げが必要かを具体的に説明できるようになります。また、サービスクォータが引き上げられないパラメータの上限値に達した場合には、アーキテクチャの改善などを検討する判断材料にもなります。

3. ボトルネックの早期発見
複雑なシステムでは、構成要素が増えるほど弱点やボトルネックに気づきにくくなります。IoTデバイス、Lambda、Amazon SQS、DynamoDBなど、多くのサービスが連携する場合、個々のサービスの制限を事前にすべて把握して、そこからボトルネックを推測するのは現実的ではありません。
リリース前に負荷試験を行うことで、「429 TOO_MANY_REQUESTS」などのエラーによって具体的なボトルネックを発見できます。そこから構成の見直しやサービスクォータの引き上げ申請といった対応をとることができます。


4. パフォーマンス最適化とチューニング
AWS Lambdaは、同じ構成でもバッチサイズやメモリ設定、Concurrencyなど、細かいチューニングによってパフォーマンスとコストのバランスが大きく変わります。負荷試験の結果を見ながら設定を調整することで、最適なパフォーマンスを実現できます。
特にコールドスタート(初回起動時の遅延)の影響も考慮すると、複数回の負荷試験実施でコールドスタートが発生する時としない時の条件下でパフォーマンスを確認することが重要です。また、アクセス集中時に安定したパフォーマンスが必要な場合は、Provisioned Concurrency(プロビジョニングされた同時実行数)の設定も検討が必要かもしれません。しかし、実行するときだけ課金対象になるLambdaの良さを消してしまい、コストが高くなってしまうのでその点は注意が必要です。

負荷試験の実施方法
計画段階
負荷試験は必ず計画と結果をセットで記録に残しましょう。計画には以下の項目を含めます:
- 負荷試験の目的(性能検証なのか、スパイクテストなのか)
- 測定・検証方法
- 適用するユースケース、シナリオ
- 負荷をかける量、回数、頻度、時間
- 費用の概算見積、タグ仕様
- 想定される課題・サービスクォータ引き上げ対象
おすすめツール
1. Distributed Load Testing on AWS
Distributed Load Testing on AWSはAWS公式のソリューションで、AWS CloudFormationテンプレートで簡単に環境構築できます。Apache JMeterで作成したシナリオを流用できたり、Webインターフェースから操作できたりと使いやすいのが特徴です。Amazon CloudWatchメトリクスとの統合により、テスト結果の分析も容易です。

2. Locust
LocustはPythonベースのオープンソースツールで、HTTPだけでなく MQTTなど様々なプロトコルの負荷試験に対応しています。Amazon ECSクラスターで構成することもできますし、カスタムクライアントで Lambdaを使うこともできます。分散負荷テストのサポートも充実しています。

3. Serverless Artillery
Serverless ArtilleryはNode.jsベースのツールで、サーバーレスアーキテクチャに特化した負荷テストが可能です。AWS Lambdaを使用して分散負荷テストを実行できるため、大規模な負荷テストも効率的に行えます。YAML形式で簡単にテストシナリオを記述できるのも特徴です。

実施時の注意点
負荷試験を始める前に、いくつか心得ておきたいポイントがあります。
第1に負荷は少しずつ段階的に増やしていきましょう。いきなり大量のリクエストを送るのではなく、100リクエスト/秒から始めて、1,000、そして10,000と徐々にスケールアップしていきましょう。
また、負荷試験中はログやトレーシングのデータ量が通常よりも大幅に増えることを忘れないでください。特にサーバーレス環境では、これらもすべて従量課金の対象になります。コストを抑えるためには、テスト中は CloudWatch Logsのログレベルを ERRORだけに設定するといった工夫が有効です。すべてのリクエストやレスポンスを記録する必要はなく、問題が発生した箇所だけ詳細に確認できれば十分なケースが多いでしょう。
負荷試験は、連携しているシステムにも影響を与える可能性があります。自分たちのシステムだけでなく、接続している他のサービスにまで大量のリクエストが流れてしまう可能性があります。そういった事態を避けるため、外部システムとの連携部分はモックに置き換えるなど、テスト対象の適切な切り分けが必要です。特に本番環境に近いステージング環境でテストする際は重要です。
最後に、AWS上で負荷テストを行う際の注意点として、特にネットワーク集中型のテストでは事前申請が必要なケースがあります。例えば 1 Gbpsを超えるトラフィックを生成する負荷テストを行う場合などは、AWSに事前連絡する必要があります。思わぬトラブルを避けるためにも、テスト前には必ず AWSの負荷テストに関するポリシー を確認して、必要な申請手続きを済ませておきましょう。
まとめ
サーバーレスアーキテクチャでは、インフラストラクチャの細かなことを気にせずに開発そのものに集中できることがメリットです。しかし、自動スケーリングや従量課金制といったサーバーレスの特性をより活かし、メリットを最大化するためには負荷試験が重要です。
その恩恵は、コスト予測、サービスクォータ引き上げ判断、ボトルネック発見、パフォーマンス最適化など、長期的な運用を考えると、どれも見過ごすことができないものばかりです。
適切な計画を立て、段階的にテストを行い、結果を分析・記録することで、より安定したサーバーレスシステムを構築できるでしょう。みなさんもぜひ、サーバーレスシステムのリリース前に負荷試験を検討してみてください!