なぜ、あなたの開発したシステムが遅いのか?第3回

Co-Wellのエンジニアによるシステム開発担当者のための情報共有BLOGです。

林隆洋

なぜ、あなたの開発したシステムが遅いのか?

担当:林 隆洋(Takahiro Hayashi)
Global Innovation Headquarters
Web制作会社、個人事業主を経て2011年株式会社コウェルに参画。 Web黎明期からPerl CGI~Java~Flash/Flex~PHPなどカバーする開発言語を拡大。 2014年から2017年までベトナムに3年ほど駐在しCTOとして教育カリキュラム構築、大学連携などに従事。 近年はセキュリティ方面に注力。2018年からMagentoの性能向上についてのプロジェクトに参画。

前回の第2回では、性能改善の最初の対策として弊社でも良くあるインフラ側の手立てについてご紹介した。
最終回となる今回は、実際に本質的な改善をするに当たって、アプリケーション側をどのように対策していくのか、最も実践的な部分を説明していく。

1. スケールアウトの準備で見落としがちなPOINT

まず、スケールアウト【 scale out 】 とは、コンピュータシステムの性能を増強する手法の一つで、システムを構成するサーバーの台数を増やすことで、システムの処理能力を高めることをいう。

何らかのトラブルでサーバーが故障しても別のサーバーでカバーできるため、システムの可用性が高まり安定運用が可能となり、処理を並列化、分散化できるシステムで主に適用される。例えば、Webサーバーのように主にWriteではなくReadが多いシステムにおいて、数多くのアクセスを分散処理で対応するような場合、サーバーの台数を増やすスケールアウトが適している。

一方、巨大なデータベースへのアクセス速度を向上させるには、サーバー同士の連携が必要になるため、単にサーバー数を増やすスケールアウトでは、あまり効果が見込めないので注意が必要だ。 ロジックの改善について論ずる前に、前回で「インフラ側の改善に関わる部分」について説明しきれていなかったのでここで取り上げておこうと思う。

APサーバとDBサーバから構成されるシステムにおいては、ユーザからのアクセスを受け付けるAPサーバを複数台並べ、ロードバランサで負荷分散および可用性の向上を図る構成が一般的とされる。

ロードバランサの役割としては、1)システムに対するリクエストを複数のサーバに分散させ、処理のバランスを調整する、2)メンテナンス時には切り離し可の仕組みで、ロードバランサを導入することにより、スケーラビリティ(拡張性)とアベイラビリティ(可用性)などを実現することができる。


<<セッション情報の管理での注意点>>


ログインなどをさせるサイトになってくるとユーザーのセッション情報を保持させなくてはならない。 サーバをスケールアウトする際、ロードバランサー側のセッション単位でサーバを固定する設定にしていない場合は、アプリケーション側の対応が必要となる。ロードバランサー側ではスティッキーセッションなどと呼ばれたりするが。例えばAWSではApplication Load Balancer(ALB)を使っている場合はこれが使える。

AWSのロードバランサーの種類としては、ELB (Classic Load Balancer)、ALB (Application Load Balancer):、NLB (Network Load Balancer)となり、Network Load Balancer(NLB)を使っている場合はこの機能が無いため、ユーザのリクエストをどのサーバに飛ばすかを固定できない。

単一のサーバーでサービスを行っている場合は特に問題にはならないが,複数のサーバーでアクセスを受けるとなるとセッションの情報は共通で持っておく必要がある。

PHPでは、通常の設定ではセッション情報はファイルとしてサーバに保存されている。従って、リクエストのたびに処理するサーバが変わってしまうと、セッションを維持できないということになる。よって、セッション情報はLocalで保存される形式を使用するのではなく外部に保存するようにすると良い。

大抵のアプリケーションフレームワークは、セッションをファイル以外の場所に保存する事が出来るので、どのサーバからも参照できる場所(データベースやキャッシュサーバ)に保存する様なイメージで設定変更すれば良いだろう。



※補足<ELBの種類>--------------------
・ALB:Application Load Balancer HTTP トラフィックおよび HTTPS トラフィックの負荷分散に最適なロードバランサ。Webサイトのロードバランサとして使用するのであれば、このロードバランサがおすすめ。
・NLB:Network Load Balancer
TCPトラフィックなどネットワーク系の負荷分散に最適なロードバランサ。
・ELB:Classic Load Balancer
複数のAmazon EC2インスタンスにおける基本的な負荷分散を行うのに最適なロードバランサ。



2. ロジックのボトルネックを探る

そもそも、APMとは、主に企業の基幹システムなどを担うWebアプリケーションのレスポンス状況を監視、様々な機能の応答時間を調べることによって、アプリケーション全体の稼働状況を管理するシステムをいう。

APMを導入により、レスポンス遅延などアプリケーションの不具合を予兆の段階で察知し、障害の発生を未然に防ぐことが可能となり、実際に問題が生じた場合、調査時間を削減するメリットがある。

これらアプリケーションに対して管理者が直面する課題として下記のことが挙げられるだろう。よって下記の条件を満たすツール選びが必須となる。

・アプリケーションの使用状況やステータスを忠実に可視化
・パフォーマンスのボトルネックであるJ2EEやJavaコンポーネントの特定
・アプリケーションの遅延の原因であるSQLクエリの特定と、JVM パフォーマンスの監視
・優れたユーザーエクスペリエンスを提供するための、最適なアプリケーションのトラブルシューティング

BlackfireやNew Relic、AppDynamicsといったAPM(アプリケーション性能管理)ツールを使ってどのように問題点を探り、どのような改善をするかが重要だ。

①重いメソッドを探る
   ↓
②重い原因を探る(多すぎる繰り返し処理)
   ↓
③クエリの最適化
   ↓
④アーキテクチャ変更を伴うか?難しい決断



3. 単体テストの有無がジワジワ効いてくる

性能改善のコード修正は機能に影響を及ぼしてはならない。その際に単体テストがあれば、安心して性能改善のリファクタリングを進めることが出来る。



4. リリースは慎重に

普通のプロジェクトでは、機能面の改修は日々行われているはずだが、そんな中で性能改善のコードをマージするとなると、場合によっては色々な影響を及ぼすことになる。よってリリース計画は慎重に行うべし。



なぜ、あなたの開発したシステムが遅いのか<最後に>

これまで全3回にわたって「あなたの開発したシステムがなぜ遅いのか、遅いと言われずにリリースするにはどうしたらよいか?」について述べてきた。

開発後に問題が明らかになるシステムの性能問題について、頭を抱える開発エンジニアは多いだろう。 もっとも、性能やセキュリティといった非機能要件を開発フェーズで意識するのとしないのとでは結果は全く異なってくる。

問題が発生した際には、まずはどこが遅いのかを可視化するためにNew RelicやDynatraceなどのツールを用いて現状を正確に把握し、JMeterで負荷をシミュレートして問題箇所を探る。ここから先は、優先順位を決めて冷静に対処していくことだ。

よく感覚的に「遅い!」と言われる場面があるが、指標が無ければ現場としてはどこから手を付ければ良いのか悩むだけなので、性能目標値を決めていく。

システム全体で重い部分が見えてきたら、Blackfireなどのプロファイリングツールを用いて詳しく分析しよう。その後は、要件を阻害しない範囲で解決策をひねり出すしかない。 流れとしてはこうだが、文字だけで見ると、あまりにも容易なように見えてしまうのがなんとも悲しい。

pagetop