本連載では、現場でのエンジニアの経験から得られた、アプリケーション・サーバをベースとしたWebシステム開発における注意点やヒントについて解説する。巷のドキュメントではなかなか得られない貴重なノウハウが散りばめられている。読者の問題解決や今後システムを開発する際の参考として大いに活用していただきたい。(編集局)
さまざまな対策を講じたにもかかわらずパフォーマンスが向上しないときの切り札として、レスポンスキャッシュが有効なことがある。レスポンスキャッシュは、コンテンツをキャッシュし、同様のリクエストに対してはキャッシュからレスポンスを返す。レスポンスキャッシュはアプリケーションサーバ固有の機能であるため、製品によってその機能は若干異なる。
アプリケーションサーバ(以下、APサーバ)に関連したトラブルの中でも、性能問題はひときわ厄介な存在である。最悪の場合、あれこれと対策を講じた揚げ句、アプリケーション自体に手を加えなければならないこともある。そんなときには、レスポンスキャッシュの利用を考えてみるのもよい。
レスポンスキャッシュはアプリケーション自体に手を加えることなくパフォーマンスを向上させることができる、まさに魔法のつえである。本稿ではレスポンスキャッシュ機能の概要や効果とともに、どのようなコンテンツで使用すべきかについても解説する。
レスポンスキャッシュとは、WebブラウザからのJSPやServletに対する初回アクセス時に生成した処理結果をキャッシュしておき、以降のアクセスに対してはキャッシュした処理結果を返す機構である。
2回目以降のアクセスでは、キャッシュされた処理結果をそのまま返すため、JSP/Servletから後ろの業務処理が省略される。これによって応答時間が短縮し、またリソースの消費量も低減する。
レスポンスキャッシュは各APサーバ固有の機能であるため、製品によってその機能に若干の相違がある。例えば主要なAPサーバのうち、WebSphere V5では処理結果のページをキャッシュするのに対し、WebLogic Server 7.0ではページ全体のほか、その一部分だけをキャッシュすることも可能となっている。
ページ全体をキャッシュする場合には既存のアプリケーションに一切手を加えることなく、APサーバの設定変更のみでパフォーマンスの向上(応答時間の短縮、CPU使用率の低減)を達成できる。一方、ページの一部分をキャッシュする場合には、該当個所をタグ指定する必要があり、アプリケーションに若干の変更が必要となる。
ここまでの説明であれば、すべてのページをキャッシュ対象とすれば劇的にパフォーマンスが向上すると思われるかもしれない。しかし実際にそのような設定を行うことは非常に危険である。
なぜならレスポンスキャッシュでは、JSP/Servletの処理結果はJVMの管理するヒープ(メモリ領域)上にキャッシュされるが、ヒープのサイズは有限であるため、ページをキャッシュし過ぎると領域が圧迫され、ガベージコレクションが多発し、かえって性能が劣化するためである。
またJSP/Servletから生成される処理結果は、JSP/Servletへのリクエストパラメータ(HttpServletRequest#getParameter()メソッドで取得する文字列)をキーとして識別され、個別にキャッシュされる。このため1つのJSP/Servletをキャッシュの対象にしたとしても、リクエストパラメータの種類が多いページでは、多くの処理結果がヒープ上にキャッシュされることになり、前述の理由から性能が劣化する。また頻繁に更新が必要な処理結果では、キャッシュの効果はほとんど得られない。
このためキャッシュ対象の選定には注意を払う必要があるが、大まかには以下のような基準で選定するとよい。
・キャッシュするにふさわしいページ
その情報を必要とするクライアントが多い、または更新頻度が少なく再利用されやすいもの。あるいは処理結果パターンの少ないもの。
例)商品の価格情報、株式日報など
・キャッシュするのは控えた方がよいページ
その情報を必要とするクライアントが限定される、または更新頻度が多く再利用されにくいもの。あるいは処理結果パターンの多いもの。
例)ショッピングカート、個人情報など
データベース(以下、DB)からデータを取得して表示するページをキャッシュした場合、キャッシュされた時点で、そのページが持つデータと、DB内にあるデータは独立して存在することになる。このためほかのJSPやServletによってDB内のデータが更新されると、キャッシュされたページが持つデータとの間で不整合が生じる。
これについて、商品の価格情報を表示するページを例に図示してみよう。
整合性の取れたページ情報を提供し続けるには、キャッシュされているページを破棄し、更新を反映させて再作成する必要がある。破棄されたページは新規アクセスによって再作成されるため、実際には破棄の方法とタイミングのみ考慮すればよい。
破棄の方法はAPサーバによってさまざまであるが、一般的にはAPIを介して破棄する、キャッシュ保持期間(タイムアウト)を指定するなどいくつかの方法がある。DBデータの更新と完全に同期させなければならない価格情報のようなページではAPI方式を利用し、多少のタイムラグは許容できるランキング情報のようなページではタイムアウト方式を利用するなど、ページ情報の特性に応じて選択するとよい。
ページごとに業務処理内容および発行するSQLの種類、数が異なるため、机上にて性能向上の割合を見積もることは困難である。ここではパフォーマンス向上を示す例として、当方にて実施したベンチマーク結果を紹介する。
ベンチマークには、書籍情報DBから、指定したジャンル名をキーとして新刊書籍を検索し表示するというアプリケーションを使用した。新刊書籍情報は不特定多数から参照されるためキャッシュの効果が期待でき、またジャンル数(リクエストパラメータ数)も限られていることから極端に多くの種類の処理結果をキャッシュしてヒープが圧迫されるという心配もない。
ページはJSPで記述し、JavaBeansおよびEJB(Stateless Session Bean)を経由してDBに対しSELECT文を1回発行するという非常に単純なものである。なおAPサーバにはWebLogic Server 7.0を用いた。
レスポンスキャッシュを使用しない場合の応答時間、CPU使用率をそれぞれ1とした場合の性能比を下図に示す。
応答時間はレスポンスキャッシュを使用しない場合の約50%減、CPU使用率は約70%減と、大きくパフォーマンスが向上した。
このように、レスポンスキャッシュはキャッシュするページの種類、DBとの整合性などに十分注意する必要があるものの、パフォーマンスの向上に対して非常に有効な手段である。積極的に利用してみてはいかがだろうか。
入内島正之
現在、株式会社NTTデータビジネス開発事業本部に所属。 技術支援グループとして、J2EEをベースにしたWebシステム開発プロジェクトを対象に、技術サポートを行っている。特に、性能・信頼性といった方式技術を中心に活動中。
Copyright © ITmedia, Inc. All Rights Reserved.