🐳

新機能のパフォーマンス課題を解決して安全にリリースするためにやったこと

2024/06/10に公開

はじめに

こんにちは、株式会社ログラスでエンジニアをしている上田(@ueda1013)です。

ログラスへの入社後、最初に担当した新機能の開発では、ユーザー体験に重大な悪影響を及ぼす可能性のあるパフォーマンス課題に直面しました。

今回の記事では、実際にどういったパフォーマンス課題に直面し、テストやチューニングを経て、どのように安全にリリースすることができたのか、その実践例をご紹介します。

また今回は、パフォーマンス課題を解決するプロセスの全体像や各プロセスの目的にフォーカスするため、開発した機能の実装、パフォーマンス劣化の原因、技術的な解決方法などの詳細は割愛しています。

その機能、安全にリリースできそう?

私がプロジェクトに参加したのは、既にある程度の機能開発が完了し、一部のお客様にβ版が公開された後でした。このタイミングで、次のような懸念点が浮上しました。

  • 新機能のメモリ使用量が非常に多く、AWS ECS on Fargate の安定稼働に懸念がある
  • 新機能を使用した場合の画面表示の速度(レイテンシ)が数十秒以上遅延する場合がある

これらのパフォーマンスの懸念が大きい機能を安全にリリースするためには、非機能要件を明らかにし、テストを通じて開発している機能がこれらの要件を満たしているかどうかを確認する必要がありました。要件を満たしていない場合は、パフォーマンス劣化の原因となるボトルネックを特定し、どのような対策が必要なのか明らかにすることが重要です。

非機能要件を明らかにする

まず最初に、非機能要件を明らかにしました。具体的には、今回のプロジェクトでは以下のような要件を設定しています。

  1. Full GCが発生しないメモリ使用量に抑えること
  2. 典型的なユースケースにおいて、画面表示の速度(レイテンシ)が指定した秒数を超えて劣化しないこと

これにより、リリースの可否を判断する基準とすることができ、自分たちでプロジェクトの進捗状況を把握しやすくなります。また、リリースに向けた関係者とのコミュニケーションもスムーズに進行するようになりました。

非機能要件に基づいたテスト設計

次に、非機能要件に基づいたテスト設計を行います。

非機能要件を満たしているかどうかを判断するために、テストによって何を明らかにする必要があるのか、どのような条件下でどのようなテストが必要なのか、以下のような観点について詳細化していきます。

  • メモリへの負荷が高いユースケースとその再現方法
  • メモリ使用量や画面表示の速度(レイテンシ)など計測する指標とその計測方法
  • 必要となる検証環境(DBのデータ量に依存するのかどうかなど)

テスト実施

テスト設計が完了したら、必要な環境を整え、実際の動作を確認しながらテストを実施して、テスト結果を計測し、まとめます。

パフォーマンスが非機能要件を満たしていない場合、実装修正後に再度テストを行い計測する必要があります。そのため、テスト手順を分かりやすくドキュメントにまとめておくことも重要です。

パフォーマンス改善と再計測

テストの結果、非機能要件を満たせておらず安全にリリースできそうになかったため、次に取り組むのはボトルネックの詳細な調査やパフォーマンス改善です。

パフォーマンス劣化の仮説を立てる

まず最初に、メモリ使用量や画面表示の速度(レイテンシ)のパフォーマンス劣化の原因について仮説を立てました。以下の点が主な仮説です。

  • 新機能で使用しているライブラリの処理に大量のメモリが必要になっているのではないか?
  • 特定のユースケースで画面表示の速度が著しく低下することがあるのではないか? 特にデータ量が大規模である場合に、遅延が大きくなるのではないか?

調査と原因の究明

仮説に基づいて以下のような調査を行いました。

  • 新機能で使用しているライブラリやその周辺の計算にどのくらい時間がかかっているかをDatadogのAPMで調査
  • 大規模なデータを用いて、特定のユースケースでの画面表示の速度やメモリ消費量を調査

その結果、1回の計算には数ミリ秒程度しかかからない処理でも、データ量が大規模である場合、その計算処理を直列に実行してしまっているため、数十秒以上のパフォーマンス劣化に繋がることが判明しました。

パフォーマンス改善と再計測

調査結果に基づき、Coroutinesを使用して計算処理を並列化することでメモリ使用量を効率化する改善を実施しました。その後、改めてテストを行ったところ、以下の結果が得られたため、無事に非機能要件を満たすことができました。

  • メモリ使用量
    • ECSのメモリ利用量が大幅に減少し、システムの安定性が向上
  • 画面表示の速度(レイテンシ)
    • データ量が大規模である場合のレスポンスタイムが改善し、負荷の高いケースでも指定された秒数以内に収まるケースが増えた

想定外の事象に対する備え

パフォーマンス改善に成功し、非機能要件を満たせそうであることが確認された後も、リリース後の想定外の事象に備えることが重要です。リリース後の早期の問題検出と対応が求められるため、モニタリング体制を整えることにしました。

モニタリング体制の整備

リリース後のパフォーマンスを継続的に監視するために、以下のモニタリング体制を整えました。

  • ダッシュボードの作成
    • Datadogに、新機能のメモリ使用量やレイテンシをリアルタイムで監視し異常な動作を早期に検出できるダッシュボードを作成しました
  • 日次の定点観測
    • リリース後の一定期間は、パフォーマンス状況を日次でモニタリングし、チームに共有しました。これにより、リリース後のパフォーマンス状況を常に把握し、必要に応じて迅速に対応することが可能になりました

結果的にリリース後は障害もなく安定した品質で機能提供できました。

まとめ

今回の新機能のパフォーマンス課題を解決して安全にリリースするためにやったことをフローチャートにまとめると、次のようになります。

また、振り返ってみると、いくつかの重要なポイントがありました。

まず、非機能要件の設定です。これにより、リリース可否の基準を明確にし、プロジェクトの進捗状況を把握しやすくなります。また関係者とのコミュニケーションもスムーズになり、全員が同じ目標に向かって取り組むことができます。

次に、丁寧な計測とエビデンスに基づく意思決定です。テスト設計と実施、そして得られたデータに基づいた調査と改善が、パフォーマンス課題の解決に直結しました。

また安全にリリースできると自信を持てる状態にしたとしても、想定外の事象は起こりうるため、リリース後のモニタリング体制の構築まで丁寧に進めることで、万が一の障害にも備えることができたのも良かったと感じています。

以上、パフォーマンス課題に直面している皆さんにとって、この記事が参考になれば幸いです。

最後までお読みいただきありがとうございました!

株式会社ログラス テックブログ

Discussion