...

2

by user

on
Category: Documents
58

views

Report

Comments

Description

Transcript

2
2 パフォーマンス管理
この章では、WAS を使用した Web システムにおいてパフォーマンスを向上させるための考慮点につ
いて説明します。
3-1 ではパフォーマンスを計測する際の代表的な指標としてスループットと応答時間について説明し
ます。3-2 では、パフォーマンス向上のために WAS で提供されている機能として動的キャッシュについて
説明します。3-3 ではパフォーマンスを向上させるためのパフォーマンス・チューニングとチューニングを
目的としたモニタリングの方法について説明します。チューニング方法については一般論を紹介してお
り、各パラメーターの最適値は実際の環境およびアプリケーションによって異なりますのでご注意くださ
い。
2-1 パフォーマンス
この節では Web システムにおけるパフォーマンスの代表的な指標としてスループットと応答時間(レス
ポンスタイム)の2つについての一般的な考え方について説明します。
2-1-1 パフォーマンスの指標
Web システムにおけるパフォーマンスの代表的な指標はスループットと応答時間によって測られま
す。以下、それぞれについて説明します。
•
スループット:単位時間(秒)あたりにシステムによって処理されるリクエスト数です。ユーザーから
のリクエストを一度にどれだけ処理できるかを表す値であり、システム全体の処理能力を表してい
ます。
•
応答時間:ユーザーがリクエストを出してから、すべての結果が戻るまでの時間でユーザーから
見た処理能力になります。どんなにスループットが大きくても、各々のユーザーにとって応答時間
が重要な点に注意しなくてはなりません。システムの負荷を判断する指標になり得ます。
システムの性能評価を行う際、横軸を同時ユーザー数、縦軸をスループットとしてプロットしたスループ
ットのグラフや、横軸を同時ユーザー数、縦軸を応答時間としてプロットした応答時間のグラフを作成し
て分析を行っていきます。
2-1-2 スループット
図 2-1ではWebシステムにおいて、同時アクセス数の増加に応じたスループットの変化の典型的なパ
ターンを一例として示しています。アプリケーションやシステムの設定でボトルネックを除去した状態が前
提です。データの推移によって、Aゾーン、Bゾーン、Cゾーンに分けて、それぞれのゾーンでシステムが
どのような状態であるかを知ることができます。
図 2-1 スループット
•
A ゾーン:同時アクセス数の増加に伴い、スループットは増加します。この段階では、システムは
すべてのリクエストを滞留させることなく処理できている状態といえます。
•
B ゾーン:CPU が 100%に達した後も同時アクセスを増加させると応答時間は悪化しますが、スル
ープットは増加します。同時アクセス数がシステムの許容量(飽和点)を超えると、スループットは
それ以上伸びなくなり、落ち始めます。
•
C ゾーン:飽和点をさらに超えると、スループットは落ち始め、Web システムとしては不健全な状態
となります。これはあまりにもアクセス数が多すぎるため、ネットワーク資源の競合やページング
等が頻発し、本来のシステムの能力が発揮できなくなった状態です。
CPU 使用率が低いにも関わらず、スループットが飽和点に達する場合、システムの能力を活用できてい
ません。他の要因がボトルネックになっている可能性があるので、ボトルネックを追及して解消する必要
があります。
想定される同時アクセス数に対して、A ゾーンまたは B ゾーンの範囲でシステムが稼動するように、チュ
ーニングを行っていきます。
2-1-3 応答時間
図 2-2では、Webシステムにおいて、同時アクセス数の増加に応じた応答時間の変化のパターンを示し
ています。
図 2-2 応答時間
一般に、システムに対するリクエスト数が増加すると、システムに余力のある場合は応答時間に大きな変
化はありません。
リクエスト数がシステムの処理能力を超えると応答時間は急速に悪化します。その場合でも、システムが
適切にチューニングされていれば、処理しきれないリクエストはエラーで戻すなどの処理によって、応答
時間は一定の限度内に収めることができます。チューニングが不適切な場合は、いつまで待っても応答
が戻らないような事態も発生し得ます。
想定されるリクエスト数に対して、充分なスループットを持つシステムを設計する必要があると同時に、要
件を満たす応答時間を実現するようにパフォーマンス・チューニングを行う必要があります。
システムの能力を充分に活用し、適切なスループットと応答時間を得るためには、パフォーマンス・チュ
ーニングを欠かすことはできません。
2-2 動的キャッシュ
Web システムのパフォーマンスを向上させる 1 つの手法にキャッシングがあります。しかし、近年の
Web サイトではより質の高いサービスを提供するために、動的なページ生成が主流となり、従来の静的
コンテンツのキャッシュに加えて、動的に生成されるコンテンツをサーバー・サイドでキャッシュすること
で、サーバーの負荷を軽減する重要性が増しています。WAS では、V4 以降、動的コンテンツをキャッシ
ュする動的キャッシュ機能をサポートしています。この節では、動的キャッシュ機能についての説明、お
よびその設定手順について説明します。
2-2-1 キャッシュされるコンテンツ
動的キャッシュ機能をより有効に活用するためには、キャッシュすべきコンテンツの決定や、Web ペー
ジのデザインが重要になります。
多くの場合、動的コンテンツのページの中身は、より小さい単位での静的コンテンツやコマンドの実行
結果などのコンポーネントを組み合わせて生成されています。例えば図 2-3のような株のポートフォーリ
オを表示するページを例にとると、ページ全体としては個人ユーザー向けに生成されていても、個々の
銘柄情報に関するデータベースへの問い合わせ結果や、共通のヘッダーやフッターなどをキャッシュ
することで、多くのユーザー向けのページを生成する際に再利用することができます。特にデータベー
ス・アクセスは非常に負荷が高い処理のため、データベースへの問い合わせ結果をキャッシュすること
でパフォーマンスを大幅に向上させることができます。WAS ではサーブレットやJSPの実行結果、コマン
ドの実行結果およびオブジェクト自体をキャッシュすることで、さまざまな粒度でキャッシュを活用するこ
とが可能です。
キャッシュさせるデータはある程度の有効期間があるものや、有効期間は短くても多くのリクエストに
再利用できるものが最適です。
図 2-3 株のポートフォーリオ・ページ
2-2-2 動的キャッシュ・サービス
動的キャッシュ機能とは、JSP やサーブレットなどの動的コンテンツやコマンドの実行結果を WAS 上に
キャッシュする機能です。この機能を利用することで、アプリケーション・サーバーおよびデータベース・
サーバーなどのバックエンド・サーバーの負荷を軽減し、クライアントに対するレスポンス・タイムを短縮
することが可能となります。
動的キャッシュ・サービスは、アプリケーション・サーバーの Java 仮想マシン(JVM)内で動作し、オブ
ジェクトの出力を保管したり、キャッシュからそのオブジェクトを提供したりします。個々のキャッシュされ
たオブジェクトはキャッシュ・エントリーと呼ばれ、JVM ヒープに保管されます。また、キャッシュは同一複
製ドメイン内に所属するアプリケーション・サーバー間で共有することが可能です。
WAS V6.1 の動的キャッシュでは以下のキャッシュをサポートします。
•
サーブレット/JSP・キャッシュ
•
コマンド・キャッシュ
•
オブジェクト・キャッシュ
•
Web サービス・キャッシュ
アプリケーション・サーバー
Webサー
バー
Web
ブラウザー
キャッシュ
キャッシュ
Web アプリケーション
プロキシー・
サーバー
図 2-4 動的キャッシュ
キャッシュ可能なオブジェクトやキャッシュの振る舞いは cachespec.xml ファイルという XML ファイルで
定義され、個々のキャッシュ・エントリーにはキャッシュ ID というユニークな ID が付けられ識別されます。
このキャッシュ ID は cachespec.xml ファイルで定義されたルールに従って生成されるか、もしくは Java コ
ーディングを使用して生成することができます。
サーブレット/JSP・キャッシュ
サーブレットおよび JSP の実行結果を保存します。WAS はサーブレットの service メソッドへの要求を
インターセプトし、キャッシュ内のコンテンツに対する要求であればキャッシュからレスポンスを返します。
キャッシュに存在しない場合は、実際に処理を実行し、実行結果をキャッシュします。キャッシュされるコ
ンテンツはキャッシュ・エントリーと呼ばれ、サーブレット/JSP・キャッシュは、HTTP リクエストのパラメータ
ーや属性、URI、セッション情報、Cookie 情報、パス情報、HTTP ヘッダー情報などを元に個々のエント
リーとしてキャッシュし、任意のキャッシュ ID を付与して管理することが可能です。
コマンド・キャッシュ
コマンド・キャッシュはサーブレット・JSPキャッシュよりもさらに細かい単位でのキャッシュを可能にする
もので、コマンド・オブジェクトの実行結果を保存します。たとえば図 2-3は、株のオンライン・トレードの
ページ例で、ユーザー向けにパーソナライズされたAccount Summaryと、多くのユーザーにとって共通
の情報となるMarket Summaryなどから構成されます。ユーザーが保持する株の情報などを含む
Account Summary はユーザーごとに異なる表示となりますが、Market Summaryで表示される各銘柄の
情報は多くのユーザー・リクエスト間で共有可能な情報です。コマンド・キャッシュでは、これらのデータ
を個々のユーザー向けのWebページ生成時ではなく、その前のデータ・アクセスの段階でキャッシュす
ることで、より高いキャッシュの効果が望めます。
コマンド・キャッシュのコマンドとは、デザイン・パターンの1つであるコマンド・パターンのコマンドを指
します。WAS ではこのコマンド・パターンに基 づいたフレームワークとして WebSphere Command
Framework という API が提供され、この Command Framework に基づいてアプリケーションを実装するこ
とで、コマンド・オブジェクトをキャッシュすることが可能となります。
オブジェクト・キャッシュ
WAS V6 から新規にサポートされた機能で、Java オブジェクトのインスタンスをキャッシュに保管し、共
有することができます。オブジェクト・キャッシュでは、ユーザーがアプリケーション・ロジックの中でキャッ
シュを利用するロジックを書きます。キャッシュを保管する領域であるキャッシュ・インスタンスを JNDI 名
に よ り ル ッ ク ア ッ プ し 、 ル ッ ク ア ッ プ し た キ ャ ッ シ ュ ・ イ ン ス タ ン ス に 対 し て
com.ibm.websphere.cache.DistributedMap インターフェースを使用してキャッシュ・エントリーの保管や取
出しを行います。コマンド・キャッシュ同様に、データベース・アクセスやビジネス・ロジックの実行結果な
ど生成負荷の高いオブジェクトをキャッシュすることで、アプリケーション・サーバーやデータベースの負
荷を軽減することが可能となります。
Webサービス・キャッシュ
Web サービス・キャッシュでは、サーバー・サイドでの Web サービスの応答をキャッシュします。またクラ
イアント・サイドでのキャッシュもサポートされています。
2-2-3 キャッシュのロケーション
キャッシュを活用する際には、前述の何をどの粒度でキャッシュするかの決定に加えて、どこでキャッ
シュするかが重要となります。
コマンド・キャッシュやオブジェクト・キャッシュはアプリケーション・サーバー上の動的キャッシュ・サー
ビスによってキャッシュされますが、サーブレット・キャッシュはアプリケーション・サーバー上の他に、外
部の Web サーバーやキャッシュ・サーバーにキャッシュさせることが可能です。外部キャッシュ上ではキ
ャッシュ・エントリーは URI に基づいて管理されます。
一般的に、よりクライアント・サイドに近い外部キャッシュ上でキャッシュされるほうがレスポンス・タイム
を向上し、サーバー・サイドの負荷を減らすことが可能ですが、キャッシュするコンテンツによっては、個
人情報や機密情報、認証が必要な情報などを含み、セキュアなロケーションに配置する必要がありま
す。一般的には、ユーザーの固有情報や機密情報などを含むデータは認証サーバーの背後やセキュ
アなゾーンにキャッシュします。
図 2-5は、Webシステムを形成する典型的な層構成と、各層でのキャッシュ可能なコンテンツを示してい
ます。動的キャッシュはWASが配置されるプレゼンテーション層やビジネス・ロジック層で使用されます。
その他の層は外部キャッシュとして、下記のコンポーネントにキャッシュを配置可能です。
•
•
動的キャッシュ
プレゼンテーション層
ビジネス・ロジック層
外部キャッシュ例
Web サーバー・プラグインの ESI キャッシュ
IBM HTTP Server の FRCA
プロキシー層
Webサーバー層
Caching
Proxy
負荷分散
装置
Caching Proxy
キャッシュ
IHS
プラグイン
ESIキャッシュ
外部キャッシュ
FRCA
キャッシュ
プレゼンテーション層
ビジネス・ロジック層
Web コンテナー
EJB コンテナー
サーブレット・
キャッシュ
オブジェクト・
キャッシュ
オブジェクト・
キャッシュ
コマンド・
キャッシュ
コマンド・
キャッシュ
WebSphere Caching Proxy
図 2-5 キャッシュのロケーション
2-2-4 キャッシュ・インスタンス
キャッシュを保持する領域をキャッシュ・インスタンスと呼びます。キャッシュ・インスタンスは動的キャッ
シュ・サービスがデータを保管し、取り出し、共有するためのロケーションを提供します。キャッシュ・イン
スタンスは複数定義することが可能であり、キャッシュ・インスタンス毎に JNDI 名を定義します。これらの
キャッシュ・インスタンスは、独立して存在し、他のキャッシュ・インスタンスの影響を受けません。またキャ
ッシュ・インスタンスごとにキャッシュ・サイズやキャッシュ・エントリーの優先順位、ディスク・オフロードの
有無などを設定できます。
アプリケーション・サーバー上で稼動するアプリケーションは、アプリケーション・サーバーが同一複製
ドメインに所属していれば他のアプリケーション・サーバー上のキャッシュ・インスタンスにアクセスするこ
とも可能です。WAS V6.1 では 2 つの種類のキャッシュ・インスタンスをサポートします。
サーブレット・キャッシュ・インスタンス
サーブレット、JSP、コマンド・オブジェクトおよび SOAP リクエストなどを保持するキャッシュ・インスタン
スです。サーブレット・キャッシュ・インスタンスを指定するには動的キャッシュの構成ファイルである
cachespec.xml ファイル中の<cache-instance>タグで指定します。キャッシュ・インスタンスを指定しなかっ
た場合は、デフォルトで用意されているキャッシュ・インスタンス(JNDI 名 services/cache/basecache)が使
用されます。
オブジェクト・キャッシュ・インスタンス
Java オブジェクトを保持、分配、共有するキャッシュ・インスタンスで、以下の API を使用することでア
プリケーションがオブジェクト・キャッシュ・インスタンスにアクセスすることが可能です。
•
com.ibm.websphere.cache.DistributedObjectCache
•
com.ibm.websphere.cache.DistrbutedMap
ア プ リ ケ ー シ ョ ン は 、 JNDI 名 に よ り キ ャ ッ シ ュ ・ イ ン ス タ ン ス を ル ッ ク ア ッ プ し て 使 用 し ま す 。
DistributedMap および DistributedObjectMap インターフェースは非常にシンプルな API で、これらの
API を利用し、アプリケーションは Java オブジェクトへの参照をキャッシュに保管することで Java オブジェ
クトをキャッシュし共有することが可能です。
DistributedMap および DistributedObjectCache に関しての詳細は WAS V6.1 InfoCenter を参照してく
ださい。
2-2-5 キャッシュの複製
クラスタリング化されたアプリケーション・サーバー間でキャッシュ・エントリーを共有する機能がキャッ
シュの複製機能です。キャッシュ・エントリーを複数のアプリケーション・サーバー間で共有することで、キ
ャッシュのヒット率を向上させることが可能です。キャッシュの複製にはデータ・レプリケーション・サービ
ス(以下 DRS)が使用されます。キャッシュを共有するアプリケーション・サーバーは同じ複製ドメインに
所属する必要があります。なお、DRS はセッション・オブジェクトの複製にも使用することができますが、
動的キャッシュの複製に使用するドメインとセッション・オブジェクトの複製に使用するドメインは分けるこ
とが推奨されます。これは、セッション・オブジェクトの複製と動的キャッシュの複製では、複製先の数が
異なるためです。セッション・オブジェクトは必ずしも全サーバーに複製する必要はありませんが(オリジ
ナル以外に最低 1 つ以上存在すればよい)、動的キャッシュはすべてのアプリケーション・サーバーに
複製を配置する必要があるからです。
2-2-6 キャッシュの無効化
キャッシュを使用する上で非常に重要なのはいつキャッシュを無効化するかです。キャッシュとオリジ
ナルのコンテンツやキャッシュの元となるデータベース上などのデータとの一貫性を保持することが大前
提となります。従来の静的コンテンツのキャッシュのようにあらかじめ想定した有効期限を設定する方式
では、データの整合性を厳密に管理できないため、オリジナルのコンテンツやデータ対する変更をトリガ
ーに、関連するキャッシュを無効化しキャッシュ・インスタンスから削除する仕組み(キャッシュの無効化)
が必要になります。WAS V6.1 では以下の方法で動的キャッシュの無効化をサポートします。
•
時間ベース – キャッシュが作成されてから指定する秒数を経過することによるエントリーの削除
•
グループ・ベース (依存関係 ID による無効化)– 作成されたキャッシュを cachespec.xml ファイル
を使用して
Dependency ID(依存 ID)規則によりグループ化し、任意のタイミングでグループ
単位でエントリーを削除
•
LRU ルール・ベース – キャッシュ・インスタンス内のキャッシュ・エントリーが溢れた際に Least
Recently Used(以下 LRU)ルールによる最も使われていないエントリーを削除
•
Java コーディング – com.ibm.websphere.cache.DistributedMap インターフェースに定義された
メソッドを呼び出すことによる削除
2-2-7 ディスク・オフロード
同時に保存されるキャッシュ・サイズがキャッシュに使用可能なメモリー・サイズより大きい場合にはデ
ィスク・オフロードの使用を検討します。
キャッシュ・インスタンスはインスタンス毎に最大キャッシュ・サイズをエントリー数で指定することができ
ます(デフォルトは 2000 エントリー)。あらかじめキャッシュ・エントリーに優先度を設定しておくと、この最
大キャッシュ・サイズを超えた場合、キャッシュは優先順位と LRU ルールに従い、メモリーから削除され
ますが、ディスク・オフロード機能を使用すると、メモリーから削除されるキャッシュ・エントリーをディスク
上に退避させておくことが可能となります。ディスクに退避されたキャッシュ・エントリーに対するアクセス
が発生すると、そのキャッシュ・エントリーは再びメモリー上にロードされ、別のキャッシュ・エントリーが
LRU ルールにしたがってディスクへと退避されます。なお、頻繁にアクセスされるキャッシュ・エントリー
は常にメモリー上においておくために、高い優先順位をつけておくことが推奨されます。
2-2-8 cachespec.xmlファイル
動的キャッシュでのキャッシュ方法に関する動作は cachespec.xml ファイルによって定義されます。
cachespec.xml では、キャッシュ可能オブジェクトとそのキャッシュ方法を定義します。またキャッシュ・エ
ントリー間の依存関係やタイムアウト、無効化に関してのポリシーもこのファイルで定義します。キャッシュ
可能なオブジェクトは、<cache-entry>エレメントで定義し、各キャッシュ・エントリーに対して、どこにキャッ
シュするか(WAS のどのキャッシュ・インスタンス上か、外部キャッシュ上かなど)、どんな情報をもとにキャ
ッシュを区別してキャッシュしていくか(どのようにキャッシュ ID を生成するか)、キャッシュの無効化をど
のようにして行うか(どの依存 ID を使ってキャッシュをグルーピングしグループ単位で無効化する)など
を定義します。
cachespec.xml ファイルはアプリケーション・サーバーの開始時およびファイルが変更されたときに動
的に読み込まれます。動的キャッシュ・サービスは新しいサーブレットやキャッシュ可能なオブジェクトが
初期化されるたびに、この記述を元に、キャッシュを行い、キャッシュ ID を生成します。
cachespec.xml ファイルはアプリケーションのデプロイメント・モジュール内に同梱することも、グローバ
ル・レベルでの設定として<WAS_root>/properties ディレクトリーに配置することも可能ですが、アプリケ
ーションのメンテナンスを考慮して以下のデプロイメント・モジュール内に配置することが推奨されます。
•
モジュール・レベルでの設定
Web モジュールの WEB-INF ディレクトリ
EJB モジュールの META-INF ディレクトリ
2-2-8-1 Dynamic Cache Policy Editor
Dynamic Cache Policy Editor は動的キャッシュのポリシー定義である cachespec.xml ファイルを作成す
るためのツールです。このツールは cachespec.xml ファイルの妥当性をスキーマと照らし合わせて評価し
たり、ポリシーを定義する際のアシスタント機能などを持ちます。さらにサーブレットや JSP を解析し、キャ
ッシュ・ポリシーを構成ファイルに追加定義するツールもサポートします。
この Dynamic Cache Policy Editor は Eclipse のプラグインとして提供されています。なお、このプラグイ
ンは、WebSphere Studio Application Developer (以下 WSAD) V5.1.0 以上か Application Server
Toolkit (以下 AST) V5.1.0 以上で使用可能です。2005 年 9 月時点では Rational Application
Developer V6.1 および AST V6.1 では使用できません。
なお、Dynamic Cache Policy Editor は以下の URL からダウンロード可能です。
http://www.alphaworks.ibm.com/tech/cachepolicyeditor
2-2-9 動的キャッシュの設定
ここでは動的キャッシュの設定方法を説明します。使用する動的キャッシュによって、必要となる構
成手順は以下のとおりです。
サーブレット・キャッシュ
1). 動的キャッシュ・サービスの有効化2-2-9-1]
2). キャッシュ・インスタンスの作成(オプション) [2-2-9-2]
3). cachespec.xmlファイルによるキャッシュ・ポリシーの定義 [2-2-9-7]
4). 無効化ロジックのアプリケーションへの作りこみ(オプション)
コマンド・キャッシュ
1). WebSphere Command Framework に基づいたアプリケーションの開発
2). 動的キャッシュ・サービスの有効化 [2-2-9-1]
3). キャッシュ・インスタンスの作成(オプション)[2-2-9-2]
4). cachespec.xmlファイルによるキャッシュ・ポリシーの定義 [2-2-9-7]
オブジェクト・キャッシュ
1). DistributedMap インターフェースを用いたアプリケーションの開発
2). 動的キャッシュ・サービスの有効化 [2-2-9-1]
3). キャッシュ・インスタンスの作成(オプション) [2-2-9-2]
以降ではそれぞれのステップでの設定内容を説明します。
2-2-9-1 動的キャッシュ・サービスの有効化
いずれの構成においても、動的キャッシュ・サービスの有効化は必須の作業となります。以下の手順
にしたがって動的キャッシュ・サービスを有効化します。
1). 管理コンソールから[サーバー]→[アプリケーション・サーバー]→[AppServer_name]を選択しま
す。
2). サーバーの管理画面で[コンテナー設定]→[コンテナー・サービス]下の[動的キャッシュ・サービス]
を選択します。
3). [サーバー始動時にキャッシュを使用可能にする]をチェックし[OK]を押下し構成を保存します。
図 2-6 動的キャッシュ・サービスの有効化
また、この画面では、キャッシュ・サイズのエントリー数やデフォルト優先順位およびディスク・オフロー
ドの設定が可能です。キャッシュ・サイズに関しては2-2-9-4、ディスク・オフロードの設定に関しては
2-2-9-5を参照してください。ここで設定した内容はグローバル設定として扱われ、動的キャッシュ・サー
ビスのデフォルトでの設定値となります。キャッシュ・インスタンス単位やcachespec.xmlファイルで個別に
設定するとその内容で上書することが可能です。なお、動的キャッシュ・サービスに設定された内容はア
プリケーション・サーバーを再起動するまで有効になりません。
2-2-9-2 キャッシュ・インスタンスの作成
キャッシュ・インスタンスを作成するには、使用したい動的キャッシュに合わせて作成するキャッシュ・イ
ンスタンスの種類を指定します。例えばサーブレット・キャッシュの場合は、管理コンソールから[リソー
ス]→[キャッシュ・インスタンス]→[サーブレット・キャッシュ・インスタンス]を選択します。
キャッシュ・インスタンスはセル、ノード、クラスター、サーバーの各レベルで設定可能です。設定した
レベルにより、キャッシュ・インスタンスのJNDI名の解決に影響がありますので注意してください。図 2-7
はクラスター・レベルでの設定例になります。
図 2-7 キャッシュ・インスタンス設定の有効範囲
キャッシュ・インスタンスの設定画面では、以下を設定します。
•
名前: キャッシュ・インスタンスの管理用の名前
•
JNDI 名: アプリケーションからルックアップする時に使用する JNDI 名
•
キャッシュ・サイズ: 最大キャッシュ・エントリー数
その他、このキャッシュ・インスタンス単位でのディスク・オフロード(2-2-9-5ディスク・オフロードの設定
(p.13)」参照)や複製の設定(「2-2-9-6 キャッシュの複製(p.15)」参照)もこの画面から設定可能です。な
お、キャッシュ・インスタンスの作成はオプションで、キャッシュ・インスタンスを明示的に作成しない場合
はデフォルトのキャッシュ・インスタンスが作成され、使用されます。
図 2-8 キャッシュ・インスタンスの設定
2-2-9-3 サーブレット・キャッシングの設定
サーブレット・キャッシングの設定はサーブレット・キャッシングを有効にしたいアプリケーション・サー
バーごとに行います。管理コンソールから[サーバー]→[アプリケーション・サーバー]→
[ApplicationServer_name]→[Web コンテナー設定]→[Web コンテナー]→[サーブレットのキャッシ
ュを使用可能にする]をチェックします。
これらの設定はサーブレット・キャッシングを行うすべてのアプリケーション・サーバーに対して行いま
す。また、設定はアプリケーション・サーバーを再起動するまで有効になりません。
図 2-9 サーブレット・キャッシュの設定
2-2-9-4 キャッシュ・サイズの設定
WASの動的キャッシュでは、キャッシュされたオブジェクトをJVMメモリーに保管します。キャッシュに
使用できるメモリーのサイズからキャッシュに保管可能な最大エントリー数を決定し、キャッシュ・サイズに
設定します。キャッシュ・サイズには 100 から 200,000 の整数を指定することができますが、キャッシュ自
体はメモリー上に保管されるため、キャッシュに使用可能なメモリー領域から、キャッシュされる個々のエ
ントリーのサイズを元に適切な最大エントリー数を決定してください。キャッシュ・サイズは図 2-6 動的キ
ャッシュ・サービスの有効化 (p.11)」の設定画面でデフォルトのキャッシュ・インスタンスに対してキャッシ
ュ・サイズを指定するか、図 2-8 キャッシュ・インスタンスの設定12)図 2-8 キャッシュ・インスタンスの設
定 の設定画面で個々のキャッシュ・インスタンスに個別に設定することもできます。
なお、ディスク・オフロードの設定を行うことで、キャッシュ・サイズを超えたエントリーをディスクに退避
させることも可能です。設定手順については、「2-2-9-5ディスク・オフロードの設定」を参照してください。
2-2-9-5 ディスク・オフロードの設定
ディスクのオフロード機能を使用する場合は、キャッシュ・インスタンスに対して設定を行います。デフォ
ルトのキャッシュ・インスタンスを使用する場合は、 [サーバー]→[アプリケーション・サーバー]→
[ApplicationServer_name]→[コンテナー・サービス]→[動的キャッシュ・サービス] を選択し、図 2-6 動
的キャッシュ・サービスの有効化(p.11)」から下記設定を行います。個々のキャッシュ・インスタンスに対し
て設定を行う場合は、[リソース]→[キャッシュ・インスタンス]→[オブジェクト・キャッシュ・インスタンス(ま
たはサーブレット・キャッシュ・インスタンス)]→[<CacheInstance_name>]を選択します。(ここで、適切な
有効範囲を指定していないと、キャッシュ・インスタンスが表示されませんので注意してください)
•
ディスク・オフロードを使用可能にする
ディスク・オフロードの使用可能の有無を設定します。ディスクにオフロードされたキャッシュ・エン
トリーは、再度必要になると、ファイル・システムからメモリーに戻されます。
•
オフロード位置
ディスクに保管されるキャッシュ・エントリーの保管場所を指定します。オフロード位置を省略した
場
合
は ”<WAS_root>/diskoffload/Node_name/ApplicationServer_name/_dynacache/<CacheJN
DI_name>” が使用されます。保管場所を指定した場合は、ノード名、サーバー名およびキャッシ
ュ・インスタンス名が自動的に追加されます。例えば、”<WAS_root>/diskoffload” を指定した場
合
は
、
実
際
に
”<WAS_root>/diskoffload/Node_name/ApplicationServer_name/<CacheJNDI_name>”
が使用されます。なお、この値はディスク・オフロードが無効にされている場合は無視されます。
•
ディスクへのフラッシュ
サーバーの停止時にメモリー内のキャッシュ・オブジェクトをディスクに保管する場合に選択しま
す。このオプションを選択する場合は、ディスク・オフロード機能を使用可能にする必要がありま
す。また、ディスクへのフラッシュ機能を使用しない場合は、サーバーの停止時にすべてのキャッ
シュ・オブジェクトが削除されます。
ディスク・オフロードのチューニング
ディスク・オフロード機能ではパラメーターを使ったチューニング項目があります。これらのパラメータ
ーはカスタム・プロパティーとして設定します。チューニングはすべてのキャッシュ・インスタンスにわたっ
て設定することもキャッシュ・インスタンス単位で設定することも可能です。
なお、ディスク・オフロードを使用する際には、ディスク書き込みのパフォーマンスを最適化するために
ファイル・システムやディスク装置のチューニングも同時に行ってください。
すべてのキャッシュ・インスタンスに対してのカスタム・プロパティーを設定するには以下のステップを
実行します。
1). 管理コンソールから[サーバー]→[アプリケーション・サーバー]→[ApplicationServer_name]→
[Java およびプロセス管理]→[プロセス定義]→[Java 仮想マシン]→[カスタム・プロパティー]から
[新規作成]を押下します。
2). カスタム・プロパティーの名前を設定します。
3). 設定した名前に対して値を入力します。
4). 構成を保存してアプリケーション・サーバーを再起動します。
サーブレット・キャッシュ・インスタンス単位でカスタム・プロパティーを設定するには以下のステップを
実行します。
1). [ リ ソ ー ス ] → [ キ ャ ッ シ ュ ・ イ ン ス タ ン ス ] → [ サ ー ブ レ ッ ト ・ キ ャ ッ シ ュ ・ イ ン ス タ ン ス ] →
[<CacheInstance_name>]→[カスタム・プロパティー]→[新規]を押下します。
2). カスタム・プロパティーの名前を設定します。
3). 設定した名前に対して値を入力します。
4). 構成を保存してアプリケーション・サーバーを再起動します。
オブジェクト・キャッシュ・インスタンスのカスタム・プロパティーを設定するには、[リソース]→[キャッシ
ュ・インスタンス]→[オブジェクト・キャッシュ・インスタンス]→[<CacheInstance_name>]→[カスタム・プロ
パティー]→[新規]を押下し同様にカスタム・プロパティーを作成します。
ここでは 3 つのカスタム・プロパティーが設定可能です。
•
ディスク・キャッシュのクリーンアップ時間の調整
com.ibm.ws.cache.CacheConfig.htodCleanupFrequency カスタム・プロパティー
このプロパティーではディスク・キャッシュのクリーンアップ間の時間を分単位で指定します。デフ
ォルトでは、”0”に設定されており、クリーンアップは毎日深夜 12 時に実行され、期限切れのキャ
ッシュ・エントリーおよび過去 24 時間の間にアクセスされなかったキャッシュ・エントリーを除去す
るようにスケジュールされています。例えば”60”に設定すると 60 分おきにクリーンアップが実施さ
れます。
•
遅延オフロード関数の調整
com.ibm.ws.cache.CacheConfig.htodDelayOffloadEntriesLimit
com.ibm.ws.cache.CacheConfig.htodDelyOffload
遅延オフロード関数は、依存関係 ID およびテンプレート ID 用に追加のメモリーを使用することで
ディスク・オフロードの実行を遅延させ、入出力操作を最小化するかどうかを指定します。
−
com.ibm.ws.cache.CacheConfig.htodDelayOffloadEntriesLimit で は 、 依 存 関 係
ID およびテンプレート ID 用バッファーとしてメモリーに保管できるキャッシュ ID の数を
指定します。デフォルトでは”1000”に設定されており、これは各依存関係 ID またはテ
ンプレート ID は 1000 の異なるキャッシュ ID までメモリーに保管することができること
を意味します。なお、設定できる最小値は”100”になります。
−
com.ibm.ws.cache.CacheConfig.htodDelyOffload では追加のメモリー・バッファー
を、依存関係 ID およびテンプレート ID 用に使用するかどうかを指定します。デフォ
ルトでは”true”(使用可能)に設定されており、この設定によりディスク・オフロードを遅
らせ、ディスクへの入出力操作を最小化します。しかし、ほとんどのキャッシュ ID が
100 バイト以上の場合、この設定を有効にするとメモリーを使いすぎる可能性がありま
す。なおこのプロパティーを”false”に設定した場合、すべてのキャッシュ・エントリーは
メモリー・キャッシュから除去されると即時にディスクにコピーされます。
2-2-9-6 キャッシュの複製
キャッシュの複製機能では、一度作成されたキャッシュ・データをクラスター内の他のアプリケーショ
ン・サーバーに複製します。この機能により複数アプリケーション・サーバーで同じ要求を実行する実行
時間や実行中に使用するリソースを節約することが可能となります。またキャッシュの複製は無効化機能
もサポートしているため、複数アプリケーション・サーバー間でのキャッシュの一貫性を保つことができま
す。
ここでは以下の設定手順を説明します。
1). 複製ドメインの作成
2). キャッシュの複製の設定
キャッシュの複製にはデータ・レプリケーション・サービスが使用されます。キャッシュの複製を使用す
るためには、まずは複製ドメインを作成します。管理コンソールから[環境] →[複製ドメイン] を選択し、
複製ドメインの設定画面で[新規作成] を押下します。
図 2-10では作成する複製ドメインの名前、要求タイムアウト、暗号化の有無などを設定します。またここ
で、レプリカの数は必ず[ドメイン全体]を選択します。これはキャッシュの複製では、クラスター内の他の
アプリケーション・サーバー全てに対して複製を行うためです。
図 2-10 複製ドメインの作成
次にキャッシュの複製の設定を行います。以下の手順で設定します。
1). 管 理 コ ン ソ ー ル の [ サ ー バ ー ] → [ ア プ リ ケ ー シ ョ ン ・ サ ー バ ー ] か ら 設 定 し た い
[ApplicastionServer_name]を選択します。
2). [コンテナー・サービス]→[動的キャッシュ・サービス]を選択します。
3). 図 2-11で[キャッシュ複製を使用可能にする]をチェックし、[フル・グループ複製ドメイン]には先ほ
ど作成した複製ドメインを指定します。
4). 図 2-11でさらに複製タイプと[push頻度]を設定します。(詳細は後述)
5). 上記ステップ 1-4 を、キャッシュの複製を行うすべてのアプリケーション・サーバーに対して行いま
す。
6). 設定が終了したら構成を保存します。
図 2-11 キャッシュ複製の設定
なお、キャッシュの複製の設定は、キャッシュ・インスタンス毎に異なる設定を行うこともできます。キャ
ッシュ・インスタンス単位で設定する場合は、使用しているキャッシュ・インスタンスの一般プロパティー画
面から同様の設定を行います。
複製タイプの設定
[複製タイプの設定]には以下のモードが設定可能です。
•
push と pull の両方
このモードに設定すると、キャッシュは必要に応じてコピーされます。アプリケーション・サーバー
は、キャッシュ・エントリーを作成すると、複製ドメイン内の他のアプリケーション・サーバーに新しく
更新されたコンテンツのキャッシュ ID を送ります。各アプリケーション・サーバーはクライアントか
らの要求を受け取ると、その要求に対するキャッシュ ID が存在するかをあらかじめ把握している
ため、キャッシュ・コンテンツを保持するサーバーからコンテンツを受け取るか、存在しない場合は
自身で要求を処理して新しいキャッシュ ID を生成します。
•
push のみ
このモードに設定すると、キャッシュ ID およびそのコンテンツは自動的に複製ドメイン内のすべて
のアプリケーション・サーバーに複製されます。したがって、全てのアプリケーション・サーバー内
にキャッシュ・エントリーの複製が常に置かれることになります。
•
共有しない
このモードに設定すると、キャッシュおよびキャッシュ ID はアプリケーション・サーバー間で共有さ
れません。
push頻度
[push 頻度]には新しいキャッシュ・エントリーや更新されたエントリーを他のサーバーに送信する頻度
を秒で指定します。0 に設定された場合、キャッシュ・エントリーは即座に送信されます。0 より大きい値を
設定するとその間に作成または変更された全てのキャッシュ・エントリーがバッチ的に送信されます。た
だし、キャッシュの無効化はここで設定した秒数とは別に即座に実行されます。
cachespec.xml によるキャッシュ・ポリシーの定義
前項で設定したキャッシュ複製の設定は、cachespec.xmlファイルで設定した内容で上書きすることが
できます。cachespec.xmlファイルの各エントリーには<sharing-policy>エレメントを使用してキャッシュ複
製の設定を行うことができます。これにより、個々のエントリー単位でキャッシュ複製の設定を変更するこ
とが可能です。<sharing-policy>の値には 4 つのタイプが指定できます。詳細は「2-2-9-7 cachespec.xml
によるキャッシュ・ポリシーの定義」を参照してください。
なお、<sharing-policy>が設定されていないエントリーに対してはグローバル設定が適用されます。
2-2-9-7 cachespec.xml によるキャッシュ・ポリシーの定義
動的キャッシュ・サービスでは、キャッシュ・ポリシーを構成ファイル cachespec.xml で定義します。
cachespec.xml では、キャッシュ可能オブジェクトとそのキャッシュ方法を定義します。何をキャッシュする
かを<cache-entry>エレメントを使って定義し、各キャッシュ・エントリーに対して、どこにキャッシュするか
(WAS のどのキャッシュ・インスタンス上か、外部キャッシュ上かなど)、どんな情報をもとにキャッシュを区
別してキャッシュしていくか(キャッシュ ID の生成ルール)、キャッシュの無効化をどのようにして行うか
(依存関係 ID によるグルーピングのルール)などを定義します。
<cache-entry>エレメントは<cache>または<cache-instance>エレメント内で定義します。<cache>エレメ
ント内の<cache-entry>はデフォルトのキャッシュ・インスタンスにキャッシュされます。<cache-instance>エ
レメント内の<cache-entry>は<cache-instance>エレメントの<name>属性で指定されているキャッシュ・イン
スタンスにキャッシュされます。
以下が cachespec.xml ファイルによるポリシー定義の作成手順です。
1). cachespec.xml フ ァ イ ル を 作 成 し ま す 。 <WAS_root>/properties デ ィ レ ク ト リ ー の
cachespec.sample.xml ファイルを Web モジュールの WEB-INF ディレクトリーまたは EJB モジュ
ールの META-INF ディレクトリーに cachespec.xml ファイルとして配置します。
2). キャッシュ可能オブジェクトの識別に必要な<cache-entry>エレメントを定義します。エレメント内
の記述方法に関してはCachespec.xmlファイルの記述(p.19)」を参照してください。
3). キャッシュIDの生成ルールを作成します。詳細についてはCachespec.xmlファイルの記述
(p.19)」を参照してください。
4). (オプション)依存関係 ID ルールを指定します。<dependency-id>エレメントを使用してキャッシュ・
グループ ID を指定します。この ID は複数のキャッシュ・エントリーを同じグループ ID に関連つけ
ます。
5). (オプション)無効化 ID 生成ルールを指定します。無効化 ID は依存関係 ID と同じ方法で定義さ
れます。
6). cachespec.xml ファイルを保管します。なお、動的キャッシュ・サービスは更新済みファイルを自
動的に再ロードしますが、古いポリシー・ファイルによってキャッシュに保管されたオブジェクトは、
ファイルの更新によって無効化はされません。これらのオブジェクトは新規ポリシーにより再利用
されるか、あるいは置換アルゴリズムによってキャッシュから除去されます。
Cachespec.xmlファイルの記述
ここでは、cachexpec.xml ファイルの中から主要なエレメントについて説明します。全エレメントの詳細
については InfoCenter を参照してください。
<cache>
cachespec.xml ファイルのルート・エレメントで<cache-instance>および<cache-entry>エレメントを含みま
す。
<cache-instance>
<cache-instance name=“CacheInstance_name”></cache-instance>
明示的にキャッシュ・インスタンスを指定した場合に、name 属性にキャッシュ・インスタンスの JNDI 名
を定義します。キャッシュ・インスタンスの JNDI 名は、管理コンソールまたは wsadmin を使ってキャッシ
ュ・インスタンス作成/編集時に設定します。
<cache-entry>
キャッシュ・エントリーを記述します。キャッシュ・エントリーごとに動的キャッシュがそのエントリーを操
作する際に必要な基本情報を定義します。ここで、<cache>タグ内に指定された<cache-entry>はデフォ
ルトのキャッシュ・インスタンスに、<cache-instance>タグ内に指定された<cache-entry>は指定のキャッシ
ュ・インスタンス内にキャッシュされます。
<cache-entry>エレメントは class、name、sharing-policy、property および cache-id エレメントを含むこと
ができます。
<class>
<class> servlet |webservice | JAXRPCClient |command |static </class>
<class>は必須のエレメントで、キャッシュ対象のオブジェクトの種類を指定します。Servlet クラスはサ
ーブレット・JSP のキャッシュ、webservice クラスは Web サービス要求、JAXRPCClient クラスは Web サー
ビス・クライアントのキャッシュ・エントリーを定義する際に使用されます。また、command クラスはコマン
ド・キャッシュ、static は静的コンテンツを指定します。
定義例:
<class>command</class>
<name>
<name>name</name>
キャッシュするオブジェクトを指定します。
•
サーブレット・JSP キャッシュおよび静的ファイルの場合
cachespec.xml ファイルが Web モジュール内に配置される場合、コンテキスト・ルートからの相対
パスで指定します。
定義例:
<name> mywebApp/myjsp.jsp </name>
ファイルがアプリケーション・サーバーの properties ディレクトリーに配置されている場合は、フ
ル・パスで指定する必要があります。
•
コマンド・キャッシュの場合
キャッシュ対象オブジェクトのフル・クラス名(.class まで含む)を指定します。
定義例;
<name> com.mycompany.MyCommand.class </name>
<sharing-policy>
<sharing-policy>
</sharing-policy>
not-shared
|
shared-push
|
shared-pull
|
shared-push-pull
2-2-9-6キャッシュの複製(p.15)」で設定したキャッシュ複製のグローバル設定は、cachespec.xmlファイル
を使って個々のキャッシュ・エントリーごとに上書き設定することができます。cachespec.xmlファイルの各
エントリーには <sharing-policy>エレメントを使用してキャッシュ複製の設定を行うことができます。
<sharing-policy>の値には以下の 4 つのタイプが指定でき、クラスター構成においてキャッシュの複製に
関するポリシーを指定します。デフォルト値は”not-shared”で、また<sharing-policy>エレメントが記述され
ていない時にもこの値が適用されます。スタンドアロン・サーバー環境では”not-shared”のみが有効で
す。
ポリシー
Not-shared
サーバー間
での連携
×
メモリーの利
用効率
-
Shared-push
○
△
Shared-pull
○
○
Shared-pushpull
○
○
動作
キャッシュが生成されたアプリケーション・サーバーのみ
でキャッシュを保持し共有はされない。デフォルト値。特
定ユーザーが複数回使用するキャッシュに使用。
キャッシュのエントリーが生成されると他のアプリケーシ
ョン・サーバーにエントリーとキャッシュ ID を自動的に配
布。常に各サーバー上にキャッシュのコピーが作成され
る。耐障害性は高いがすべてのサーバーにキャッシュ
が配置されるのでリソースを多く使用する。多くのユー
ザーに使われ、かつヒット率も高いキャッシュに使用
アプリケーション・サーバーは自身のキャッシュにオブジ
ェクトが存在しない場合、他のアプリケーション・サーバ
ーに照会してキャッシュが存在するかを調べる。どのサ
ーバーにもキャッシュが存在しない場合は自分で処理
を行う。
キャッシュが作成されるとキャッシュ ID のみを他のアプリ
ケーション・サーバーに配布。これにより、アプリケーショ
ン・サーバーは特定のキャッシュ ID に対するエントリー
をどのアプリケーション・サーバーにとりに行けばよい
か、または自分で処理を実施すべきかを判断できる。
表 2-1 キャッシュ複製タイプ
<property>
<property name=”key”>value</property>
動的キャッシュのオプション構成の設定を行います。ここで Key はこのキャッシュ・エントリー・エレメン
トのプロパティー名で、value にその値を指定します。
•
edgeCacheable
EdgeSideInclude キャッシュの可否を指定します。サーブレット/JSP キャッシュを使用している際
に、”true”または”false”を設定することができます。デフォルトは”false”です。”true”に設定されて
いると、EdgeSideInclude キャッシュが可能になります。
•
externalCache
外部キャッシュ名を指定します。外部キャッシュ名は外部キャッシュ・グループ名と一致する必要
があります。
•
persist-to-disk
キャッシュのディスクへの書き込み可否を指定します。デフォルトは”true”です。”false”に設定され
ている場合、キャッシュ・エントリーはディスクに書き込まれません。
<cache-id>
キャッシュ・エントリーに付与されるキャッシュ ID を生成する方法を指定します。この ID は、ユーザー
作成のカスタム Java コードか、各キャッシュ・エントリーに定義されたキャッシュ・ポリシーのルールから生
成されます。各キャッシュ・エントリーには複数のキャッシュ ID 生成ルールを定義することが可能で、ル
ールは有効なキャッシュ ID が生成されるか、実行するルールがなくなるまで実行されます。
また、いずれのルールも有効なキャッシュ ID を生成できなかった場合は、そのオブジェクトはキャッシ
ュされません。
<cache-id> では、オブジェクトをキャッシュするた めのルールを定義します。 <cache-id> エレメントは
timeout、inactivity、priority、property、idgenerator、metadatagenerator サブエレメントで構成されます。
<cache-id>component | timeout | inacitivity | priority | property | idgenerator |
metadatagenerator</cache-id>
主な構成情報を下記に記述します。詳細は InfoCenter を参照してください。
•
<component>
キャッシュ ID の生成に使用される情報を指定します。Component サブエレメントは属性の id、
type、ignore-value および method、field、required、value および not-value エレメントなどから
構成されます。
id 属性を使用してコンポーネントを識別し、type 属性を使用してコンポーネントの種類を識別しま
す。type 属性の値には、サーブレット・キャッシュの場合 parameter、cookie、session、header、
requestType などが指定可能です。コマンド・キャッシュの場合、method、field が指定可能です。
required エレメントが、true に設定されると、キャッシュ ID 生成にはこの<component>で定義した
ルールが非ヌル値を戻さなければいけないことを示します。詳細については InfoCenter を参照し
てください。
•
<timeout>
<timeout>value</timeout>
キャッシュ・エントリーの存続時間を絶対時間を秒数で設定します。0 または負の値を設定する
と、キャッシュ・エントリーは無限に保持されます。
•
<inactivity>
<inactivity>value</inactivity>
キャッシュ・エントリーがアクセスされた最終時刻からの、キャッシュ・エントリーの存続時間を指定
するために使用します。最終キャッシュ・ヒットから数えてキャッシュを保持する秒数を指定しま
す。
•
<priority>
<priority>value</priority>
キャッシュ・エントリーの優先順位を指定します。キャッシュが最大キャッシュ・サイズに到達する
と、LRU に基づきキャッシュ・エントリーがメモリーから除去またはディスクにオフロードされる際に
使用されます。Value には 1 から 255 の整数が設定可能です。
•
<idgenerator>および<metadatagenerator>
<idgenerator>classname</idgenerator>
<metadatagenerator>classname</metadatagenerator>
これらのサブエレメントは
com.ibm.websphere.servlet.cache.IdGenerator
、
com.ibm.websphere.cache.webservices.IdGenerator
com.ibm.websphere.servlet.cache.metaDataGenerator
com.ibm.websphere.cache.webservices.MetaDataGenerator インターフェースを実装したカス
タム・クラスを用いて、独自ロジックによるキャッシュ ID の生成を行う際に使用します。classname
にクラス名を指定します。
<dependency-id>
複数のキャッシュ・エントリーをグループ化し、グループを識別する際に使用される依存関係 ID を生
成するルールを定義します。依存関係 ID は依存関係 ID 基本ストリング(キャッシュ・グループ名)と
component エレメントの値を用いて生成されます。component エレメントの指定方法は cache-id と同じで
す。
定義例
<dependency-id>CompanyCache
<component id=“company” type=“parameter”>
<required>true</required></component>
</dependency-id>
<invalidation >
キャッシュを無効化する際に、無効化するキャッシュを識別するために使用される無効化 ID を生成し
ます。依存関係 ID と無効化 ID とが一致した場合、該当する依存関係 ID を持つキャッシュ・エントリー
は全て無効化されます。指定方法は<cache-id>や<dependency-id>と同じです。
2-2-9-8 cachespec.xml記述例
「2-2-9-7cachespec.xml によるキャッシュ・ポリシーの定義(p.18)」で説明したcachespec.xmlの記述例
を紹介します。例としてここではTradeアプリケー ションを使用します。Tradeアプリケーションとは
WebSphere Application Serverのベンチマーク用アプリケーションで、以下のサイトから入手可能です。
http://www-306.ibm.com/software/webservers/appserv/was/performance.html
WAS V6.1 に対応する Trade としては Trade6 が提供されています。この Trade アプリケーションは動
的キャッシュ・サービスを活用しており、WAS V6.1 の動的キャッシュ・サービス用サンプル・アプリケーシ
ョンとしても位置づけられています。以下の Web モジュールの WEB-INF ディレクトリーに Trade6 用
cachespec.xml ファイルがあります。
<WAS_root>/profiles/<DM_profile>/config/cells/<cell_name>/applications/Trade.ear/deployments/Trade
/tradeWeb.war/WEB-INF
ここではこの cachespec.xml ファイルの一部を紹介します。Trade アプリケーションの内容についての詳
細は Trade アプリケーションに含まれるドキュメントを参照してください。
サーブレット・キャッシュの定義
例 2-1 サーブレット・キャッシュ・エントリー定義例」は、homeサーブレットに対するキャッシュ・エントリー
の定義です。homeサーブレットはユーザーが指定した処理を実行し、結果を返すサーブレットです。こ
のキャッシュ・エントリーはサーブレットのキャッシュ・エントリーのため、<class>エレメントで”servlet”を、
nameエレメントで”home”サーブレットのURIである”/app”を指定します。<cache-id>以下はこのキャッシ
ュ・エントリーに対するキャッシュIDを生成する際使用されるルールを定義しています。actionパラメータ
ーがhome(URIが/app?action=home)で、サーブレット・エンジンが有効なJSESSIONID Cookieの値を取
れる時のみキャッシュされ、キャッシュIDには、URIとJSESSIONID Cookieの値が使用されます。つまり、
/app?action=homeの結果はユーザーごとに異なるキャッシュ・エントリーとして保持されます。
ま た home サ ー ブ レ ッ ト に は 、 Account_UserID と Holdings_UserID と い う 2 つ の 依 存 関 係
ID<dependency-id>が定義されています。これらは、HTTP セッションの uidBean の値をグループ名として
グルーピングされるように定義されています。
<cache-entry>
<class>servlet</class>
<name>/app</name>
<cache-id>
<component id="action" type="parameter">
<value>home</value>
<required>true</required>
</component>
<component id="JSESSIONID" type="cookie">
<required>true</required>
</component>
<property name="EdgeCacheable">true</property>
</cache-id>
<dependency-id>Account_UserID
<component id="action" type="parameter" ignore-value="true">
<value>home</value>
<required>true</required>
</component>
<component id="uidBean" type="session">
<required>true</required>
</component>
</dependency-id>
<dependency-id>Holdings_UserID
<component id="action" type="parameter" ignore-value="true">
<value>home</value>
<required>true</required>
</component>
<component id="uidBean" type="session">
<required>true</required>
</component>
</dependency-id>
</cache-entry>
例 2-1 サーブレット・キャッシュ・エントリー定義例
コマンド・キャッシュの定義
例 2-2 コ マ ン ド ・ キ ャ ッ シ ュ ・ エ ン ト リ ー の 定 義 例 」 は コ マ ン ド ・ キ ャ ッ シ ュ を 定 義 し て い ま す 。
AccountCommandは、ユーザーのアカウント情報を取得するオブジェクトで、getUserIDメソッドの戻り値
をキャッシュIDとしてキャッシュされます。このキャッシュ・エントリーも依存関係 IDのルールから、
Account_UserIDグループに属していることがわかります。
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.websphere.samples.trade.command.AccountCommand</name>
<cache-id>
<component type="method" id="getUserID">
<required>true</required>
</component>
<priority>3</priority>
</cache-id>
<dependency-id>Account_UserID
<component id="getUserID" type="method">
<required>true</required>
</component>
</dependency-id>
<dependency-id>AllUsers
</dependency-id>
</cache-entry>
例 2-2 コマンド・キャッシュ・エントリーの定義例
無効化の定義
例 2-3 無効化の定義例」は、無効化のポリシーを定義しています。OrderCompletedCommandには無
効化ID <invalidation>としてAccount_UserIDとHoldings_UserIDが定義されています。これにより、
OrderCompletedCommandが実行されると、AccountUserIDまたはHoldings_UserID と合致するグルー
プ名(依存関係ID)でグルーピングされているキャッシュ(つまりこのコマンドを実行したユーザー名に関
するキャッシュ)は無効化されます。
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.websphere.samples.trade.command.OrderCompletedCommand</name>
<invalidation>Account_UserID
<component id="getUserID" type="method">
<required>true</required>
</component>
</invalidation>
<invalidation>Holdings_UserID
<component id="getUserID" type="method">
<required>true</required>
</component>
</invalidation>
(省略)
</cache-entry>
例 2-3 無効化の定義例
2-2-10 動的キャッシュの管理
Dynamic Cache Monitor とは、キャッシュの統計、キャッシュ・エントリーやキャッシュ・ポリシーに関する
情 報 を 表 示 す る ア プ リ ケ ー シ ョ ン で 、 CacheMonitor.ear フ ァ イ ル と し て 提 供 さ れ て い ま す 。
CacheMonitor.ear ファイルは<WAS_root>¥installableApps 下にあり、これをインストールすることで、動
的キャッシュの情報を管理し、構成情報を確認することができます。
以下に Dynamic Cache Monitor のインストール手順を示します。なおセキュリティーを考慮して、通常
のアプリケーションとは異なるホスト名とポート番号を使用するため、最初に仮想ホストを別途作成しま
す。
仮想ホストの作成
1). 管理コンソールから[環境] → [仮想ホスト] → を選択し[新規作成]を押下します。
2). 名前に仮想ホストの名前(ここでは”cache_monitor”を指定)を設定し[適用]を押下します。
3). 追加プロパティーの[ホスト別名]→[新規作成]を押下し、ホスト名に”*”(アスタリスク)、ポートに任
意のポート番号(キャッシュ管理の目的に使用するポート番号。ここでは”9070”を使用)を設定し、
[OK]を押下し、構成を保存します。
図 2-12 仮想ホストの作成
4). 次にアプリケーション・サーバーの Web コンテナーの Inbound Chain を作成します。管理コンソー
ルで[サーバー]→[アプリケーション・サーバー]→[ApplicationServer_name]→[Web コンテナー
設定]→[Web コンテナー・トランスポート・チェーン]を選択し、[新規作成]を押下します。
5). トランスポート・チェーン名に任意の名前(ここでは”CacheMonitor”を指定)を設定し、[次へ]を押
下します。
6). ポート名には任意の名前(ここでは”9070”を使用)、ホストには”*”(アスタリスク)、ポートには3) で
設定したポート番号(”9070”)を設定し[次へ]を押下します。
図 2-13 トランスポート・チェーンの作成
7). 設定した内容を確認して[終了]を押下し、構成を保存します。
8). 上記ステップ4)6)をDynamic Cache Monitorを導入する全てのアプリケーション・サーバーに対し
て実施します。このとき、同一ノード上で複数のアプリケーション・サーバーを稼動している場合は
ポート番号が重複しないように注意してください。また、1)3)で設定した以外のポート番号を使用
する場合は、都度仮想ホストの追加設定をしてください。
Cache Monitor のインストール
次に Cache Monitor アプリケーションを監視対象サーバーに導入します。
1). 管理コンソールから[アプリケーション]→[エンタープライズ・アプリケーション]→[インストール] を
選択します。
2). アプリケーション・インストールの準備画面で、CacheMonitor.ear ファイルへのパスを設定し、[次
へ]をクリックします。(デフォルトでは、<WAS_root>/installableApps の下にあります。)
3). 次の画面では、[Web モジュールにデフォルトの仮想ホスト名を指定します]を選択し、[Host
name]に先ほど作成した仮想ホストを指定します。
図 2-14 仮想ホストの指定
4). 次のセキュリティーに関する警告ページでは[継続]をクリックします。
5). [ステップ 1]ではデフォルトのまま[次へ]をクリックします。
6). [ステップ 2]では[クラスターおよびサーバー]からアプリケーションをインストールするクラスターま
たはサーバーを選択し、[Dynamic Cache Monitor]モジュールを選択して[適用]ボタンをクリックし
ます。
図 2-15 導入先サーバーの設定
7). [ステップ 3]では [Dynamic Cache Monitor]WebModule をチェックし、仮想ホストには先ほど作
成した[cache_monitor]を選択します。
図 2-16 Web モジュールへの仮想ホストのマップ
8). [ステップ 4]では[全認証者?] をチェックし [次へ]を押下します。
9). [ステップ 5]で内容を確認し、[終了]を実行し、[マスター構成に保管]を実行します。
10). アプリケーション・サーバーを再始動します。
11). Cache Monitor にアクセスするには、下記 URL を利用します。
http://<ApplicationServer_name>:<Port_number>/cachemonitor
ここで<ApplicationServer_name>には Cache Monitor アプリケーションをインストールしたサ
ーバーのアドレス、<Port_number>には、Cache Monitor 用に定義したポート番号(ここでは
9070)を指定します。なお、WebSphere セキュリティーが設定されている場合は、有効なユー
ザーID とパスワードが必要になります。
キャッシュ・モニターにアクセスすると、図 2-17のようなページが表示されます。ここからキャッシュに
関する統計を表示したり、設定内容を表示したり、キャッシュを操作することが可能です。
WAS V6.1 では新たに複数のキャッシュ・インスタンスを作成することをサポートするため、WAS V6.1
のキャッシュ・モニターでは特定のインスタンスを選択するプルダウン・メニューが新たに追加されていま
す。
図 2-17 キャッシュ・モニター画面
2-2-11 外部キャッシュ
動的キャッシュには、サーブレット・キャッシュを WAS の外部に配置し、制御する機能があります。より
クライアントに近い場所でキャッシュ・ヒットさせることにより、レスポンスが返されるまでのホップ数が減り
応答時間も向上しますし、バックエンドのシステムにかかる負荷を軽減することにもつながります。外部キ
ャッシュの配置先としては、以下の 3 つがサポートされます。なお、三つ目に挙げ ている Edge
Components の Caching Proxy は V6.1 より非推奨になりました。
•
Web サーバー・プラグインの ESI プロセッサー
•
IBM HTTP Server の高速応答キャッシュ・アクセラレーター(FRCA キャッシュ)
•
Edge Components の Caching Proxy
2-2-11-1 外部キャッシュの設定
外部キャッシュを行うには、外部キャッシュ・グループを作成してキャッシュの配置先などを指定し、キ
ャッシュ・エントリーごとのキャッシュの可否などを定義します。外部キャッシュを行うために必要な定義は
以下のとおりです。
1). 外部キャッシュ・グループ定義の作成
2). 外部キャッシュ・グループ・メンバーの定義
3). Cachespec.xml ファイルでの定義
4). 各コンポーネントでの定義
以降ではステップ 1)、2)、3)および 4)に関して、ESI キャッシュの設定方法と IHS 高速応答キャッシュ・
アクセラレーターの設定手順を説明します。
外部キャッシュ・グループとメンバーの定義
外部キャッシュ・グループは以下の手順で作成します。
1). 管理コンソールから[サーバー]→[アプリケーション・サーバー]を選択し、設定を行うアプリケーショ
ン・サーバーをリストから選択します。
2). 構成パネルで[コンテナー・サービス]→[動的キャッシュ・サービス]を選択し、追加プロパティーの
[外部キャッシュ・グループ]を選択します。
3). [新規作成]で外部キャッシュ・グループの名前を入力し、[OK]を押下し、構成を保存します。なお、
デフォルトで ESI キャッシュ用の外部キャッシュ・グループ(EsiInvalidator)が存在します。ESI キ
ャッシュを使用する場合はこのグループを利用可能です。
図 2-18 外部キャッシュ・グループの作成
次に外部キャッシュ・グループのメンバーを定義します。
4). [サーバー]→[アプリケーション・サーバー]→[ApplicationServer_name]→[コンテナー・サービ
ス]→[動的キャッシュ・サービス]から、先ほど作成した外部キャッシュ・グループを選択します。
5). [外部キャッシュ・グループ・メンバー]→[新規作成]を選択します。
6). アドレスには、アダプターBeanが外部キャッシュに接続する際に使用するアドレス、アダプター
Bean名には使用するBean名を定義します。使用する外部キャッシュに応じて表 2-2にしたがっ
て定義してください。
図 2-19 外部キャッシュ・メンバー定義
7). [OK]を押下し、構成を保存します。
外部キャッシュ・グループ・メンバーの追加時には使用する外部キャッシュに応じて下記の表にしたが
って定義してください。
外部キャッシュ
アダプター名
ESI
com.ibm.websphere.servlet.cache.ESIInvalidatorServlet
アドレス
ホスト名(:ポー
ト)
FRCA
com.ibm.ws.cache.servlet.Afpa
ポート番号
Caching
com.ibm.websphere.edge.dynacache.WteAdapter
ホスト名:ポート
Proxy
番号
表 2-2 外部キャッシュ・タイプと定義するアダプター名およびアドレス
Cachespec.xmlファイルでの定義
外部キャッシュにキャッシュさせるためのポリシーを定義します。cachespec.xml ファイルで各キャッシュ・
エントリーに以下を追加定義します。
•
ESI キャッシュ
<property name="EdgeCacheable">true</property>
•
FRCA
<property name="ExternalCache">AFPA</property>
定義例:
<cache-entry>
<class>servlet</class>
<name>/marketSummary.jsp</name>
<property name="EdgeCacheable">true</property>
<cache-id>
<priority>3</priority>
<timeout>180</timeout>
</cache-id>
<dependency-id>MarketSummary
</dependency-id>
</cache-entry>
例 2-4 cachespec.xml ファイル定義例
Edge Side Includeキャッシュの設定
Edge Side Include とは、フラグメント化された Web ページを動的に統合しページを生成するためのマー
クアップ言語を規定したオープン・スタンダードな仕様で、Web サーバー・プラグインには、Edge Side
Include (以下 ESI)プロセッサーが組み込まれています。ESI プロセッサーは Web サーバー・プラグイン
のメモリー上に動的コンテンツのフラグメントをキャッシュします。
Web サーバー・プラグインが受け取った要求は、ESI プロセッサーに送信(ESI プロセッサーが有効で
あることが前提)され、キャッ シュの有無がチェックされます。そこでキャッシュ・ミスが発生すると、
Surrogate-Capability ヘッダーが追加され、その要求がアプリケーション・サーバーに転送されます。アプ
リケーション・サーバーはサーブレット・キャッシュが使用可能になっており、かつ応答が外部キャッシュ
可能である場合、Web サーバー・プラグインへの応答として Surrogate-Control ヘッダーを戻します。
Surrogate-Control 応答ヘッダーの値にはルールのリストがあり、ESI プロセッサーはこれを使用してキャ
ッシュ ID を生成し、ESI キャッシュ内にキャッシュを保管します。
ESI キャ ッシュを使用するには、WAS 上に DynaCacheESI.ear をインストールして ください。また、
plugin-cfg.xml ファイルで ESI キャッシュの有効/無効(デフォルトでは有効になっている)と最大キャッシ
ュ・サイズおよび ESI キャッシュへの無効化通知に関する下記設定を行います。
•
ESI プロセッサーの有効化
<Property Name="ESIEnable" Value="true" />
無効化の場合は”false”を設定します。False に設定された場合、その他の設定は無視されます。
•
キャッシュ最大サイズの指定
<Property Name="ESIMaxCacheSize" Value="1024" />
キャッシュの最大サイズ(K バイト単位)を指定します。デフォルトは1M バイトです。なお、キャッシ
ュが満杯になると、もっとも有効期限に近いエントリーから削除されます。
•
無効化通知の設定
<Property Name="ESIInvalidationMonitor" Value="false" />
ESI プロセッサーがアプリケーション・サーバーからの無効化通知を受けるかどうかを指定しま
す。無効化通知を受けるためには、ESIInvalidationMonitor の値を”true”に設定します。なおこの
機能を使用するためには、DynaCacheEsi アプリケーションをアプリケーション・サーバーにイン
ストールする必要があります。
IBM HTTP Server高速応答キャッシュ・アクセラレーターの設定
IBM HTTP Server には、高速応答キャッシュ・アクセラレーター(Fast Response Cache Accelerator,
FRCA: 別名 AFPA)が提供されており、Windows 環境および AIX 環境において静的コンテンツのキャ
ッシュがサポートされます。動的キャッシュの外部キャッシュとしては Windows 環境のみがサポートされ
ます。外部キャッシュの設定は IBM HTTP Server の構成ファイルである httpd.conf に以下の 2 行を追加
定義します。なお、IBM HTTP Server が複数の WAS にリクエストをルーティングしている場合は、アプリ
ケーション・サーバーの数だけ、AfpaPluginHost を定義します。
LoadModule afpaplugin_module <WASPlugin_ROOT>\bin\afpaplugin20.dll
AfpaPluginHost <WAS_Hostname>:<port>
ここで、WAS_HostnameにはWebサーバーのホスト名を、Portにはアプリケーション・サーバー上で
AFPAコンポーネントとの通信に使用可能なポート番号を指定します。ここで指定したポート番号は、図
2-19で設定したポート番号になります。
LoadModule ibm_afpa_module modules/mod_afpa_cache.so
AfpaEnable
AfpaCache on
AfpaLogFile “<IHS_ROOT>¥logs¥afpalog" V-ECLF
LoadModule afpaplugin_module c:\WebSphere\Plugins\bin\afpaplugin20.dll
AfpaPluginHost host1:9000
AfpaPluginHost host2:9001
例 2-5 FRCA 設定例
2-3 チューニング
この 節では、パフォーマンスを向上させるためのパラメーター・チュ ーニングについて説明します。
WASでチューニングを考慮する際の基本的なポイントはキューイング・ネットワークとJVMメモリーのチュ
ーニングになります。キューイング・ネットワークのチューニングではWASだけではなくWebサーバーも考
慮する必要があります。Webサーバーのチューニングについては2-3-2
Webサーバー(p.46)で説明します。
2-3-1 キューイング・ネットワーク
キューイング・ネットワークの考え方とチューニングで設定する WAS の各コンポーネントのパラメータ
ーについて説明します。
2-3-1-1 キューイング・ネットワーク
Web アプリケーションにおいては、クライアントからのリクエストはランダムにサーバーに到達し、サー
バーが一度に受け取るリクエスト数は非常に波があるのが通常です。また、システムには許容量があり、
ある程度を超えたリクエストを同時に処理しようとすると、システム本来の性能が発揮できない可能性が
あります。このため、WAS ではリクエストが Web サーバー、アプリケーション・サーバー、データベースを
流れる際に、各々のコンポーネントの入り口で一度に処理するリクエストの数を制限します。処理しきれ
ない分は行列に並ばせ、順番に受け付けます。このときの待ち行列を「キュー」と呼び、待ち行列による
リクエスト管理を「キューイング」と呼びます。サーバーは、一定限度までのリクエストは並行に処理します
が、システムに設定された数を超えた同時リクエストは、キューに入れられ、処理の順番を待ちます。
同時リクエスト数が非常に多く、キューの中での待機時間が長くなって、キューへの送信側で設定され
たタイムアウト値を超えた場合は、クライアントにエラーとして戻されます。システムの許容量を超えたリク
エストがあった場合に、ユーザーのストレスを軽減し、システムの負荷を必要以上に大きくしないために
は適切なタイムアウトの設定も重要です。
キューには、オープン・キューとクローズド・キューの2種類があります。
•
オープン・キュー
キューの中で活動状態にあるリクエスト数に制限はありません。
•
クローズド・キュー
キューの中で活動状態にあるリクエスト数に上限があり、システムによってリソースへの同時アク
セスが管理されています。クローズド・キューの中のリクエストは、活動状態か待ち状態のいずれ
かの状態となります。活動状態とは、このリクエストが対象のコンポーネントによって現在実行中
であるか、更に先のコンポーネントによる処理の終了待ち状態である場合をいいます。待ち状態
とは、このリクエストが対象のコンポーネントによる実行待ちである場合をいいます。
アプリケーション・サーバーに対するサーブレットの実行要求は複数のコンポーネントによって順番に
処理が行われていきます。以下の図に一連の処理の例を示します。ブラウザからのリクエストはネットワ
ークを経由して、Web サーバーで受け付けられます。Web サーバーの処理を経て、WAS のコンポーネ
ントである Web コンテナーと EJB コンテナーで処理され、データ・ソースを使用したデータベース接続の
処理が行われます。Web サーバー、Web コンテナー、EJB コンテナー、データ・ソースの各コンポーネン
トにはそれぞれキューが存在し、この一連のキューのつながりをキューイング・ネットワークと呼びます。
各々のキューはクローズド・キューであり、同時に実行可能なリクエスト数に制限があります。
図 2-20 キューイング・ネットワーク
•
Web サーバーのキュー
•
Web コンテナーのキュー(オープン・キューとしても構成可能)
•
EJB コンテナーのキュー(オープン・キューとしても構成可能)
•
データ・ソースのキュー
パラメーター調整の原則
キューの中で活動状態にあるリクエスト(スレッド)の最大数を各コンポーネントのパラメーターで設定す
ることが可能です。
同時に実行可能なスレッド数を増やすことによって、ある程度はスループットの向上が望めますが、その
数はコンポーネントが稼動するマシンの能力に依存するものです。過剰なスレッドの実行はメモリなどの
リソースを必要以上に消費し、パフォーマンスの低下を招くことになります。
それぞれのパラメーターを調整して、各コンポーネントで過剰なスレッドが実行されることのない最適値
を見い出します。
各コンポーネントの一連の処理が、シームレスに処理される環境であれば各コンポーネントで設定する
パラメーターは同じ数になりますが、実際は各コンポーネントで処理可能なスレッド数は異なり、キュー
で待ちが発生することになります。
一般的には、ネットワーク側(Web サーバーの手前)で処理を待つリクエストの数を多く、アプリケーショ
ン・サーバー内部で処理を待つリクエストの数が小さくなるように調整します。リクエストの待機は、そのコ
ンポーネントへの負荷が発生するので、リクエストをできるだけネットワーク側で待たせることによってア
プリケーション・サーバーへの負荷を軽減することができます。ネットワーク側でリクエストを待機させるこ
とができない場合は、アプリケーション・サーバー側で待機させることになります。
また、バックエンド側のスレッド数を増やしたい場合は、その前段のコンポーネントのスレッド数も増加さ
せて多くのリクエストを受け付けるようにする必要があります。
図 2-21にパラメーター調整の一例を示します。クライアントから同時に到着した要求数 200 に対し、Web
サーバーへの接続待ちが 125、Webコンテナーの接続待ち、データベース(データ・ソース)への接続待
ちがそれぞれ 25 となっています。
図 2-21 パラメーター調整
理想的には、システムの負荷テストを行った上で、それぞれのキューの最大数に達したときにシステム
の CPU の使用率が 100%となり、システムの最大のパフォーマンスが得られるように、パラメータを設定
するのが良いでしょう。
アプリケーションの構成によっても、キューのパラメータを調整する必要があります。具体的には以下
の例があてはまります。
•
ほとんどのページが静的コンテンツ(HTML ファイルなど)で構成され、クライアントからの要求のう
ちサーブレットの実行を必要とするものが少ないサイトの場合、HTTP サーバーのキューのサイズ
を特に大きくする必要があります。
•
サーブレット内部での複雑な処理に CPU の 90%、データベース接続を使用した簡単な処理に残
りの 10%を使用しているアプリケーションの場合、平均すれば同時実行中のサーブレットのうち
10%のみがデータベースに同時に接続していることになります。この場合、データ・ソースのキュ
ーのサイズは、Web コンテナーのキューのサイズよりはるかに小さくて済みます。
•
逆に、処理のほとんどがデータベースに接続した状態で行われるサーブレットでは、Web コンテナ
ーのキューのサイズと、データ・ソースのキューのサイズはほとんど同じとなります。
トランスポート・チャネル
WAS V6 でチャネルフレームワークが採用されることにより、Webコンテナーのキュー構造が大きく変
更されています。
WAS V5.x では、Web サーバー経由のリクエストはデフォルトで KeepAlive 接続となるため、一度 Web
サーバーのプラグインが WAS の HTTP トランスポートに対して生成した接続は切断されることなく次回の
アクセスの際に再利用されました。これによって、接続の生成・切断にかかる時間と負荷を軽減すること
ができましたが、一方ではクライアントと Web コンテナーのスレッドが直接結びつくことで、特定のクライア
ントに Web コンテナーのスレッドが占有されるという状態がありました。
図 2-22 WAS V5 における Web サーバー-HTTP トランスポート間の接続
WAS V6.1 では TCP トランスポート・チャネルがクライアントからのリクエストを受け付け、Web コンテナ
ーのスレッドで使用可能状態であるスレッドにリクエストを割り当てていきます。Web サーバーと Web コン
テナー間が直接 KeepAlive 接続にならず間に TCP トランスポート・チャネルを介することで、特定のクラ
イアントが Web コンテナーのスレッドを占有するということがなくなりました。
Web コンテナーのスレッドは1クライアントのレスポンスを返した時点で、キューに入っているリクエストの
処理を実行することができ、より有効にスレッドが使用されます。
図 2-23 WAS V6.1 における Web サーバー-トランスポート・チャネル間の接続
負荷分散時のキューイング・ネットワーク
負荷分散装置を使用して、リクエストを複数のサーバーに分散して実行する場合は、以下の点に注
意が必要です。
•
セッション・アフィニティなどの使用により、複数のサーバーに必ずしも均等に要求が振り分けられ
るとは限りません。偏る可能性がある場合は、各サーバーで同時に受け付ける要求数を多めに
設定することが必要な可能性もあります。
•
いったん分散された要求が合流するような箇所がある場合(DB サーバーが 1 台の場合など)はそ
の部分がボトルネックにならないよう、サーバーのサイジングやパラメーターの設定に十分に注意
します。
図 2-24 負荷分散時のキューイング・ネットワーク
2-3-1-2 WASにおけるパラメーター設定
システムを構成するキューのパラメーター、特にクローズド・キューにおける要求の最大同時実行数を
調整することは、システムのスループットを向上させるうえで重要です。これらには以下のパラメーターが
挙げられます。
Webサーバー
IBM HTTP Server(以下、IHS)の場合、パラメーターの設定は、<IHS_root>/conf/httpd.confファイル
で行います。IHSの最大同時実行数はファイル中のMaxClients/ThreadsPerChildディレクティブで設定し
ます。設定値を超えた要求に対するタイムアウトは、Webブラウザーごとの実装によって決定されます。
IHSはv1.3 とv2.0/6.0 ではリクエストの処理方法が異なり、リクエストに対する親プロセス、子プロセスの振
る舞いが異なります。2-3-2-1IBM HTTP Serverのリクエスト処理方法46)を参照してください。
Webコンテナー
Web コンテナーの最大同時実行数は、アプリケーション・サーバーの Web コンテナー・スレッドのパラ
メーターで設定します。管理コンソールより、以下の手順で設定画面を表示します。
①
[サーバー] → [アプリケーション・サーバー] → [ApplicationServer_name] → [コン
テナー設定] → [Web コンテナー設定] → [Web コンテナー] を選択し、対象のアプリケー
ション・サーバーの、Web コンテナーの設定画面を表示します。
②
Web コンテナーの設定画面から、[追加プロパティ]→[Web コンテナー・トランスポート・チェ
ーン]→[WCInboundDefault]→[TCP インバウンド・チャネル(TCP 2)]→[関連項目]→[ス
レッド・プール]→[WebContainer]と選択して、スレッド・プールの設定画面を表示します。
図 2-25 Web コンテナースレッド・プール
プール内のスレッドは、[最大サイズ]で設定した値まで、作成可能です。プール内で使用されていない
スレッドは、[スレッド非活動タイムアウト経過後]に[最小サイズ]に設定したスレッド数まで破棄されます。
パラメーターの変更後は[適用]または[終了]ボタンを押下して、保管作業を行いアプリケーション・サー
バーの再始動が必要となります。
TCPトランスポート・チャネル
TCP トランスポート・チャネルで受け付ける接続の最大値は TCP インバウンド・チャネルで設定しま
す。管理コンソールより以下の手順で設定画面を表示します。
①
[サーバー] → [アプリケーション・サーバー] → [ApplicationServer_name] → [コンテ
ナー設定] → [Web コンテナー設定] → [Web コンテナー・トランスポート・チェーン] を選
択し、対象のアプリケーション・サーバーの、トランスポート・チェーンの設定画面を表示しま
す。
②
トランスポート・チェーンの設定画面から、[WCInboundDefault] → [TCP インバウンド・
チャネル(TCP 2)] を選択し、TCP インバウンド・チャネルの設定画面を表示します。
図 2-26 TCP トランスポート・チャネル
[最大のオープン接続数]で設定した数だけの接続を受け付けます。[非活動タイムアウト]ではリクエスト
がない状態で KeepAlive 接続が切断されるまでのタイムアウト値を設定します。
EJBコンテナー
EJBに対するメソッド呼び出しは、、図 2-21 パラメーター調整に示されるように、EJBクライアントが
EJBの稼動しているEJBコンテナー上ではなくリモート・クライアントからの場合に限って、キューを介して
行われます。
別プロセス内で動作する EJB クライアントからの EJB 呼び出しは、RMI/IIOP プロトコルによって行われ、
EJB コンテナー側の ORB によって処理されます。ここでは、ORB スレッド・プールが EJB コンテナーの
キューとしての役割を果たします。
ただし、ORB スレッド・プールは要求到着時に空きスレッドがない場合は、新規のスレッドを作成して要
求を実行し、このスレッドの実行が終了するとスレッドを破棄します。同時に実行されるスレッドの数に上
限が無いため、EJB コンテナーのキューはオープン・キューとなります。
EJB コンテナーのスレッド・プール・サイズは、こういったキューおよびアプリケーションの特徴を踏まえて
決定する必要があります。
管理コンソールより、[サーバー] → [アプリケーション・サーバー] → [ApplicationServer_name] →
[コンテナー設定] → [コンテナー・サービス] → [ORB サービス] → [追加プロパティ] → [スレッド・プー
ル] を選択して、スレッド・プールの設定画面を表示します。
図 2-27 ORB スレッド・プール
プール内のスレッドは、[最大サイズ]で設定した値まで、作成可能です。プール内で使用されていない
スレッドは、[スレッド非活動タイムアウト]経過後に[最小サイズ]に設定したスレッド数まで破棄されます。
パラメーターの変更後は[適用]または[終了]ボタンを押下して、保管作業を行いアプリケーション・サー
バーの再始動が必要となります。
データ・ソース
データ・ソースの最大同時実行数は、各データ・ソースの接続プールのパラメーターで設定します。管
理コンソールより、[リソース] → [JDBC プロバイダー] → [JDBCProvider_name] → [追加プロパテ
ィ] → [データ・ソース] → [DataSource_name] → [追加プロパティ] → [接続プール・プロパティ]を選
択して、接続プールの設定画面を表示します。
図 2-28 接続プール
最大同時実行数は、最大接続数で設定します。
2-3-2 Webサーバー
2-3-2-1 IBM HTTP Serverのリクエスト処理方法
IBM HTTP Server(以下、IHS)は v1.3 と v2.0/6.1 でリクエストの処理方法が異なります。(UNIX系)
•
IBM HTTP Server v1.3 の処理方法
IHS v1.3 の起動により生成された親プロセスは、子プロセスを生成して IHS に来るリクエストを処理させ
ます。同時に処理可能なリクエストの数は子プロセスの数に依存します。生成する子プロセスの数は
httpd.conf ファイルで設定可能です。最大同時実行数は MaxClients で決定され、指定された数は生成
される最大子プロセス数になります。
親プロセス
リクエスト毎に
プロセス生成・消去
子プロセス
子プロセス
子プロセス
図 2-29 IHS V1.3 のリクエスト処理(UNIX 系)
•
IBM HTTP Server v2.0/6.1 の処理方法(UNIX 系)
IHS v2.0/6.1 ではリクエストを子プロセスで処理させるのではなく、各々の子プロセスがスレッドを生成
し、そのスレッドによってリクエストが処理されます。IHS v2.0/6.0 で同時に処理できるリクエスト数は
httpd.conf ファイルで設定する MaxClients で決定されますが、指定された数はリクエストを実行するスレ
ッドの最大数を示しています。
子プロセスが生成する各スレッドがリクエストを実行することによって、IHSv2.0/6.1 は v1.3 よりも少ない子
プロセス数で多くのリクエストを実行することができます。子プロセス数の減少によって、子プロセスの生
成にかかる負荷を抑制できることができます。
親プロセス
リクエスト毎に
スレッド生成・消去
子プロセス
スレッド
スレッド
スレッド
子プロセス
スレッド
スレッド
スレッド
図 2-30 IHS V2.0/6.0 のリクエスト処理(UNIX 系)
•
IBM HTTP Server v1.3/2.0/6.1 の処理方法(Windows)
Windows 環境では、生成された親プロセスによって、1つの子プロセスが生成されます。子プロセスがス
レッドを生成し、そのスレッドによってリクエストが処理されます。最大同時実行数は ThreadsPerChild で
決定され、指定された数は生成される最大スレッド数を示しています。
図 2-31 IHS V1.3/2.0/6.0 のリクエスト処理(Windows)
IHS2.0 のスレッド生成に関するディレクティブは以下になります。
•
MaxCliens(150):サービスを行うスレッド合計数の上限
•
ThreadsPerChild(25):各子プロセスが生成できるスレッド数
•
MaxSpareThreads(25):待機状態のスレッドの数の上限
•
MinSpareThreads(25):待機状態のスレッド数の下限
•
StartServers(2):サーバー起動時に作成される子プロセスの数
•
MaxRequestsPerChild(0):1つの子プロセスが処理できるリクエストの最大数
•
ServerLimit(16):親プロセスが生成可能な子プロセスの上限
2-3-2-2 IBM HTTP Serverのモニタリング
IBM HTTP Server(以下、IHS)の mod_status モジュールを利用することによって Server status ページか
ら、IHS のプロセスがリクエストを処理する状況をモニターすることができます。
設定手順
以下に、設定手順を示します。
①
IHS の構成ファイル(<IHS_root>/conf/httpd.conf)を開き、以下のように status_module と
server-status の Location タグのコメント・アウト(#)を外します。
## Turn on extended status by default when mod_status is enabled
LoadModule status_module modules/mod_status.so
(中略)
# Allow server status reports, with the URL of http://servername/server-status
# Change the ".your_domain.com" to match your domain to enable.
<Location /server-status>
SetHandler server-status
#
Order deny,allow
#
Deny from all
#
Allow from .your_domain.com
</Location>
(後略)
「Allow from」に続くドメイン名を指定することによって、Server status ページへのアクセスを制限
することができます。指定したドメイン名のマシンからのみアクセスが可能になります。必要に応じ
て指定します。
②
構成ファイルの変更を保管して、IHS を再起動します。
③
Web ブラウザーで「http://<host_name>/server-status」にアクセスして Server status ペー
ジを表示します。URL を「http://<hostname>/server-status?refresh=5」と指定することによ
って、5 秒間隔で更新します。
図 2-32 Server status ページ
2-3-3 データベース接続
データ・ソースを使用してデータベースへの接続を行う際のパフォーマンス上の考慮点について説明
します。
2-3-3-1 接続プール・サイズ
データベースへの接続を作成する処理は、非常に負荷のかかる処理となるため、WAS では作成した
接続をプールして再利用するという仕組みになっています。プールすることができる接続の最大数はデ
ータ・ソースのパラメーターの最大接続数で設定します。
2-3-3-2 Prepared Statement Cacheサイズ
JDBC は動的な SQL のインターフェースなので、「SQL 発行→SQL 文のプリコンパイル(プリペア処
理)→実行」というプロセスが、たとえ同じ SQL が発行されたとしてもリクエストがある度に毎回繰り返され
ます。データベースにとって、プリペア処理は負荷が大きい処理なので、プリペア処理を省くことでパフ
ォーマンスの向上が望めます。
そこで、一度行われたデータベースのプリペア処理を再利用して、負荷を軽減するのが Prepared
Statement Cache の機能になります。データベース・アクセスをするアプリケーションは Prepared Statement
を利用してコーディングし、WAS でステートメント・キャッシュを利用すると、データベース側でプリペア処
理が行われた SQL が WAS にキャッシュされ、効率的にプリペア処理を省略することができます。
ステートメント・キャッシュは接続プールのコネクションごとにキャッシュされるため、以下のように設定する
ことが推奨されています。
推奨値=異なる PreparedStatement の SQL の総数
実行される SQL 文は内容が同じでも、大文字・小文字が異なると異なるステートメントとして扱われるの
で注意が必要です。
ステートメント・キャッシュ・サイズはデータ・ソースの一般プロパティで設定します。管理コンソールのナ
ビゲーション・ツリーより[リソース]→[JDBC プロバイダー]→[JDBCProvider_name]→[追加プロパティ]
→[データ・ソース]→[DataSource_name]→[追加プロパティ]→[WebSphere Application Server デー
タ・ソース・プロパティ]を選択して、WebSphere Application Server データ・ソース・プロパティのページを
表示します。[ステートメント・キャッシュ・サイズ]フィールドで、1コネクションあたりのステートメント・キャッ
シュの数を指定します。
図 2-33 WebSphere Application Server データ・ソース・プロパティ
ステートメント・キャッシュ・サイズは、Tivoli Performance Viewerで廃棄されるステートメント・キャッシュを
モニターして調整することができます。ステートメント・キャッシュ数が設定した値を超えると、キャッシュは
廃棄されていきます、廃棄が確認された場合はその数だけステートメント・キャッシュ・サイズを増加させ
るとよいでしょう。2-4-2-4モニタリング・ポイント」の6)データ・ソース接続プール」を参照してください。
2-3-4 JVM
JVM とは、Java 仮想マシン(Java Virtual Machine : JVM)のことで、Java バイトコードをそのプラットフォー
ムのネイティブコードに変換して実行するソフトウェアです。Java 言語で開発されたソフトウェアは、配布
時にプラットフォームから独立した独自の形式(Java バイトコード)になっており、そのままでは実行するこ
とができません。このため、そのプラットフォーム固有の形式(ネイティブコード)に変換するソフトウェアを
用意して、変換しながら実行します。この変換と実行を行うのが JVM です。
2-3-4-1 JVMのチューニング
Java アプリケーションの実行環境である JVM が使用する仮想ストレージは一般にヒープと呼ばれていま
す。WebSphere Application Server V6.1 の使用している JVM は IBM Developer Kit For Java 5.0 から採
用された J9 VM と呼ばれる JVM です(以後、特に断りのない限り、JVM とは WAS に搭載されている Java
仮想マシン指し示すものとします)。また、JVM のサブコンポーネントでヒープの状態管理(メモリ管理)を
担当しているのは ST コンポーネントと言います。
商品表示、決済処理、機器制御など、Java アプリケーションとして世の中に出ているソフトウェアには目
的に応じた様々な機能が実装されており、それゆえヒープには様々なタイミングで様々なオブジェクトの
割り当て要求が発生します。このように多種多様に使用される状況では、単一のメモリ管理ポリシーの運
用ではすべての使用ケースで均一のパフォーマンスを出すことができません。メモリ管理ポリシーとはヒ
ープ管理のアルゴリズムを規定するもので、GC ポリシーとも呼ばれます。JVM がデフォルトで採用して
いる GC ポリシーによって幅広い種類のアプリケーションで最適なパフォーマンスが出ると言われていま
す。ただし、今挙げた理由によりケースによってはデフォルトの GC ポリシーでは最適なパフォーマンス
が出せない場合があります。そのため JVM では複数のメモリ管理ポリシーが提供され、必要に応じて適
切なポリシーを選択できるようになっています。
一般に JVM のチューニングではポイントが二つあります。まず適切なメモリ管理ポリシーの選択を行なう
必要があります。その上で、次にシステムに合ったヒープサイズの設定を行います。この節ではまず最適
な GC ポリシーを選択するために個々の GC ポリシーの仕組みについて説明を行っていきます。ポリシ
ーを理解したうえでパフォーマンス要件を満たすために最適な GC ポリシーを選択するための指針を示
します。最後に GC ポリシー別に分けてヒープサイズのチューニング方法を解説していきます。
2-3-4-2 GCポリシー
Java プログラムの大きな特徴のひとつに JVM によるヒープ管理があります。C 言語のようにプログラマが
明示的にヒープの確保と開放を行うのではなく、それらの作業を JVM に委譲することでより安全なプロ
グラムの作成が行えるようになっています。JVM(具体的には JVM の ST コンポーネント)が提供するメモ
リ管理方法は GC ポリシーを指定することで変更することができます。ヒープにはアプリケーションによっ
て使用されるすべてのオブジェクトが格納されますが、この割り当てと使用後の整理を行うのがメモリ管
理の主な役割です。
アプリケーションの内部で new 演算子が使用されてオブジェクトの初期化が指示されると、JVM はヒープ
へのオブジェクト割り当て作業(ヒープ・アロケーション:Heap allocation)を行います。この作業は JVM が
オブジェクトの使用するメモリ領域をヒープ内に確保し、アプリケーションがその領域を使えるように参照
情報を渡します。この参照情報を取得することで、アプリケーション・スレッドはオブジェクトを実際に使
用することができるようになります。ST コンポーネントはヒープ内のどこにオブジェクトが存在するかを管
理するのではなく、ヒープ内のどこに空き領域が存在するかを管理しています。個々の空き領域はひと
つのリストによって数珠繋ぎに管理されており、ヒープ・アロケーション実施時にはリストの中からオブジェ
クトを格納可能な空き領域の検索が行われます。一般にこのヒープ内の空き領域を管理するリストを
Free list と呼んでいます。
Free list にオブジェクトを格納できるサイズの空き領域がない場合、割り当て失敗(Allocation Failure)と
なります。Allocation Failure の発生が使用していないオブジェクト(ガーベッジ)をヒープから廃棄する作
業、すなわちガーベッジ・コレクションのトリガーとなります。「ガーベッジとなった」オブジェクトとは、アプ
リケーションから参照されなくなったオブジェクトのことです。同じ観点からヒープ内の「生きた」オブジェ
クトは、スレッドのスタックや static なフィールドから直接参照しているオブジェクト(Root オブジェクトと呼
ばれています)、および Root オブジェクトやその子オブジェクトなどが参照していて Root オブジェクトか
ら到達可能になっているオブジェクトと定義できます。「ガーベッジとなった」オブジェクトと「生きた」オブ
ジェクトの大まかなイメージ図を以下に示します。
到達可能な(「生きた」)オブジェクト
(
はRootオブジェクト )
到達不可能なオブジェクト
(ガーベッジ)
Sweep対象
図 2-34 「生きている」オブジェクトとガーベッジ
ヒープ・アロケーションおよびガーベッジ・コレクションのアルゴリズムについてはこれまで沢山の研究が
行われてきており、多種多様な手法がこれまで生み出されています。WAS V6.1 で使用されている J9
VM では以下にあげる 4 つの GC ポリシーが利用可能となっています。
1. Optimize for Throughput
2. Optimize for Pause Time
3. Generational Concurrent
4. Subpooling
この 4 つの GC ポリシー共通で言えるのですが、どのポリシーでもヒープ内のオブジェクト管理方法とし
て、ガーベッジがどこにあるのかを管理するのではなく、「生きている」オブジェクトがどこにあるのかを管
理しています。「生きている」オブジェクトが使用していない領域に存在しているオブジェクトをガーベッ
ジと判断して、その領域のメモリーを開放しています。
それでは具体的に個々の GC ポリシーについて見ていくことにします。
2-3-4-3 Optimize for Throughput(-Xgcpolicy:optthruput)
まずはデフォルトの GC ポリシーである Optimize for Throughput について解説します。以降表題とともに
GC ポリシーを説明する際に JVM に渡す引数を併せて記載します。この GC ポリシーはデフォルトのポリ
シーであるため、この GC ポリシーで JVM を稼動するときには特に明示的に指定しなくても構いません。
この GC ポリシーはガーベッジ・コレクションを Mark-Sweep-Compaction の三つのフェーズに分けて実施
します。Mark フェーズではヒープ内のすべての「生きている」オブジェクトにしるし(Mark)をつけます。
Sweep フ ェ ー ズ は 、 し る し の つ い て い な い オ ブ ジ ェ ク ト を 、 ヒ ー プ 内 か ら 掃 き と り (Sweep) ま す 。
Compaction フェーズはヒープ上に存在しているすべてのオブジェクトをヒープのアドレス領域の一端に
まとめる作業が行われます。Mark フェーズと Sweep フェーズはそれぞれそれほど大きな負荷とならない
ため毎回の GC で実施されます。それに対して Compaction フェーズはオブジェクトの移動が伴うため
個々のオブジェクトのコピーとメモリアドレス情報の再構成が行われます。そのため先の二つのフェーズ
と比べると負荷の大きな作業になるため、Compaction フェーズは発生条件が整ったときにのみ実施され
ます。例えば Mark&Sweep が行われた後にヒープ・アロケーションを行えるだけの十分な空き領域が
Free list にできなかった場合や、開放できた領域が少なくて全体の空き領域が一定以下だった場合で
す Systemgc()コールの場合の除いて、Compaction は必ず一度ガーベッジ・コレクションが実施された後
に行われます。
以下に各フェーズにおけるヒープ状況のイメージを示します。
ガーベッジ・コレクション実施直前:
Mark&Sweepフェーズ実施後:
Compactionフェーズが実行された場合:
空き領域
図 2-35
割り当て済みの領域
Optimize for ThroughputGC ポリシーのガーベッジ・コレクション
以下に挙げる図は JVM のアプリケーション・スレッドの稼動状況を時間軸に沿って見てみた場合のイメ
ージです。ガーベッジ・コレクション実行中はヒープへのアクセスを行っているすべてのスレッドが停止す
るため、アプリケーションによるクライアントへのサービスもガーベッジ・コレクションが終了するまで停止し
ます。ちなみに、ヒープへのアクセスを行っていないスレッドと GC を実施しているスレッド(Allocation
Failure となったアプリケーション・スレッドがそのまま GC を実施します)はガーベッジ・コレクション中も稼
動できるようになっています。
スレッド1
スレッド2
スレッド3
…
スレッドn
時間
アプリケーション処理
ガーベッジ・コレクション(アプリケーション処理停止)
図 2-36 アプリケーション・スレッドとガーベッジ・コレクションの関係(Optimize for Throughput)
(参考)ヒープ・ロックとスレッド・アロケーション・キャッシュ
Optimize for Throughput ではひとつのヒープをすべてのスレッドが共有しています。あるスレッドがヒー
プ・アロケーションを行っているとき、そのスレッドはヒープ内の整合性を保つためにヒープに対するロッ
クを JVM から取得します。その間は他のスレッドはヒープ・アロケーションを行うことができないため、複
数 CPU によって JVM を稼動している場合はあまり効率がよくありません。そのためなるべくロック待ちの
時間を少なくする目的で、個々のスレッドは独占的に使用できる空き領域を Free list から常にひとつず
つ確保して使用しています。これをスレッド・アロケーション・キャッシュ(Thread Allocation Cache)、または
スレッド・ローカル・ヒープ(Thread Local Heap)と呼びます。この領域内ではロックを使用することなくヒー
プ・アロケーションが可能になるため、その分ロック待ちが無くなります。スレッド・ローカル・ヒープを使い
果たすと、スレッドは Free list からまた新たな空き領域をひとつ確保して、それをスレッド・ローカル・ヒー
プ用の領域として使用します(スレッド・ローカル・ヒープの領域取得はオブジェクトに対するヒープ・アロ
ケーションと同じですので、取得時にはヒープ・ロックがかかります)。メモリ分断化(フラグメンテーション:
Fragmentation)が発生しているときは Free list 内の個々の空き領域の大きさが小さくなっています。その
ためスレッド・ローカル・ヒープとして割り当てることのできる領域も小さいので頻繁に新しい領域の取得
が行われます。つまりフラグメンテーション発生時には Compaction の多発に加えてヒープ・ロックも多発
するという副次効果が発生することで、さらにパフォーマンスの低下に追い討ちをかける状況が生まれま
す。
(参考)ラージ・オブジェクト・エリア
JVM にはオブジェクトのサイズとして大きな部類と見なされる(64K バイトを超える)ようなものを格納する
領域が用意されています。これがラージ・オブジェクト・エリアと呼ばれている領域です。デフォルトではヒ
ープサイズの 5%がラージ・オブジェクト・エリアとして確保されており、その後ヒープ内に割り当てられる
アプリケーションのオブジェクトサイズに応じて最大 50%、最小 0%の間で領域の大きさが変動します。度
重なるガーベッジ・コレクションによって Free list 内の個々の空き領域が小さくなっていったような時に比
較的大きなサイズのオブジェクトの割り当てにラージ・オブジェクト・エリアが使用されることで
Compaction フェーズを回避することができ、結果としてパフォーマンスの低下を防ぎます。負荷の高い
Compaction フェーズをなるべく回避するための一方策としてラージ・オブジェクト・エリアが提供されてい
ますが、なるべく大きなオブジェクトをアプリケーションで生成しないでこの領域を使用しないように心が
けること大切です。なお IBM JDK 1.4.1 以前ではラージ・オブジェクト・エリアは Wilderness 領域と呼ばれ
ていました。
2-3-4-4 Optimize for Pause Time(-Xgcpolicy:optavgpause)
Optimize for Throughput では、JVM がガーベッジ・コレクションを実施している最中は、アプリケーショ
ン・スレッドの活動が止まっています。つまり、運悪くリクエストの到着がガーベッジ・コレクションの時間帯
にかぶってしまうと、ガーベッジ・コレクションによるリクエスト処理の停止の影響を受けるので、その分レ
スポンスが遅れます。ガーベッジ・コレクションが長くなるとその分最大レスポンス・タイムも大きくなる可
能性が出てくるわけです。アプリケーションやシステムのパフォーマンス要件によってはスループットより
もレスポンス・タイムのばらつきが小さいことがより優先されるケースもあります。そのような場合に検討対
象になる GC ポリシーがこの Optimize for Pause Time です。ヒープ管理のアルゴリズムはデフォルトと同
じ Mark-Sweep-Compaction 型を採用しつつ、文字通りガーベッジ・コレクションによる JVM の停止時間
を最小化するために最適化されたポリシーとなっています。簡単に説明するとリクエスト処理している時
間帯に Mark 処理もこまめにやってしまうことで停止時間を短縮しようというのがこのポリシーで採用され
ている方法です。各アプリケーション・スレッドはあるタイミングからヒープ・アロケーションを実施する度
に、自身の所有するスタックから到達可能なオブジェクトを追跡し Mark していく作業を行います(この段
階を Concurrent フェーズとも呼ぶことから、この GC ポリシーのは Concurrent Mark とか Concurrent GC
とも呼ばれます)。また、優先度の低いスレッドをバックグラウンドで起動して、CPU のアイドル時間を利用
して Mark 処理を並行して実施します。これらの事前作業を行うことで、ガーベッジ・コレクション時のアプ
リケーション・スレッドの停止時間を短縮します。ただし、ガーベッジ・コレクションの前に処理を行うため
に、スレッドによって事前にスキャンされたヒープ領域の状態がガーベッジ・コレクション実施時には変わ
っている場合もあります。例えば、スキャン後に新たにオブジェクトがその領域に生成されたような場合
です。そのため、ガーベッジ・コレクションの実施時にはヒープを複数の領域に分け、それぞれの領域で
スキャン後に変更された形跡があるかどうかをチェックして、変更されている領域は再スキャンが行われ
ます。
この GC ポリシーはデフォルトの Optimize for Throughput と比べるとスループットの面で不利になります。
特に Concurrent フェーズにおいて個々のアプリケーション・スレッドがリクエスト処理を行いながら Mark
作業を行うので、このフェーズが長くなればなるほどスループットは低下します。スループット低下の度
合いが高くなるか低くなるかは、並行して実施されている Mark 処理をバックエンドで行っているスレッド
の処理がどれだけ多く実施できるかによります(つまり CPU のアイドル時間を獲得できる見込みのあるシ
ステムでは有利となります)。また、アプリケーションやシステムの特性によっては再スキャンの割合が多く
なって GC 時間の短縮が実現されない可能性も考えられます。
Optimize for Throughput の時と同様に Optimize for Pause Time 適用時の時間軸に対するスレッドの稼
動状況のイメージを以下に示します。GC の前に Concurrent フェーズによるリクエスト処理と Mark 処理の
併走時間が発生し、その間はアプリケーション処理だけでなく Concurrent トレース(Mark 処理)にも CPU
時間が配分されます。Optimize for Pause Time では Concurrent トレースによって Allocation Failure が発
生する前に Mark 処理を事前に進めることで、実際にガーベッジ・コレクションが発生した時にアプリケー
ション・スレッドが停止する時間の短縮を実現します。
スレッド1
スレッド2
スレッド3
…
スレッドn
時間
アプリケーション処理
ガーベッジコレクション
Concurrentトレース
実施中は
アプリケーション処理停止
図 2-37 アプリケーション・スレッドとガーベッジ・コレクションの関係(Optimize for Pause Time)
2-3-4-5 Generational Concurrent(-Xgcpolicy:gencon)
IBM Developer Kit For Java 5.0、つまり WAS V6.1 から新たに加わった GC ポリシーがこの Generational
Concurrent です。他の例と同様、名称がこの GC ポリシーの性質をよく表しており、一般に「世代別 GC」
と呼ばれる方法を採用しています。一言で Generational Concurrent の採用しているアルゴリズムの特徴
を述べると、個々のオブジェクトの想定される生存期間に応じて、ヒープ・アロケーションを行う場所を変
えながらヒープ全体を管理するというものです。具体的なヒープ管理方法を説明していきます。ヒープを
Nursery 領域と Tenured 領域と呼ばれる二つの異なる領域に分割します。新規に生成されるオブジェクト
はまず Nursery 領域に割り当てられます。オブジェクトがある回数のガーベッジ・コレクションをくぐり抜け
て「生存」し続けることができると、オブジェクトは Nursery 領域から Tenured 領域に移されます。生成され
るほとんどのオブジェクトは数回のオーダーの回数のガーベッジ・コレクションのうちに消滅する一方で、
その期間中に生き残ったオブジェクトは比較的寿命が長いという一般則があります。そこで、「短命」の
オブジェクトに対して集中してガーベッジ・コレクションを行い、「長命」のオブジェクトはあるタイミングで
別の領域に待避させる手法をとることでガーベッジ・コレクションの効率を上げるというのがこの GC ポリシ
ーのアルゴリズムです。
Nursery 領域はさらに二つの領域に分かれ、一方を Allocate 領域、もう一方を Survivor 領域と呼びま
す。ここで Generational Concurrent でのヒープモデルのイメージ図を以下に示します。
Nursery(New)領域
(Allocate領域)
Tenured(Old)領域
(Survivor領域)
図 2-38 Generational Concurrent GC ポリシーにおけるヒープモデル
生成されるオブジェクトはまず Allocate 領域に格納されます。Allocate 領域がいっぱいになると、ヒープ
内の「生きた」オブジェクトのトレースが行われます。その際に、「生きた」オブジェクトがあるとそのオブジ
ェクトを Survivor 領域にコピーをしていきます。これによって、Allocate 領域の全体のチェックが終わる
と、「生きた」オブジェクトはすべて Survivor 領域にコピーされており、Survivor 領域を使ってこれ以降の
リクエスト処理を行えるようになっています。そこで、Survivor 領域が新たに Allocate 領域として使用さ
れ、元 Allocate 領域だったものは Survivor 領域となって次のガーベッジ・コレクションで再び役割が交代
するまで放置されます。この nursery 領域を使用したガーベッジ・コレクションを Scavenge コレクションと
呼んでいます。Scavenge コレクションが行われている間は、デフォルトの Optimize for Throughput の時と
同じようにすべてのアプリケーション・スレッドは停止します。
以下に Scavenge コレクションの間に発生する Tenured も含めたヒープ全体の状態変化のイメージを示し
ます。Allocate 領域がいっぱいになると Nursery 領域でガーベッジ・コレクションが実施されます。原則的
に「生きた」オブジェクトは Survivor 領域にコピーをされますが、ある設定された閾値を超えるガーベッ
ジ・コレクションを生き延びたオブジェクトは Survivor 領域ではなく Tenured 領域にコピーされます。
Nursery領域
Tenured領域
Scavengeコレクション
実施前:
Scavengeコレクション
実施後:
空き領域
割り当て済みの領域
図 2-39 Scavenge コレクションの実行イメージ
ある程度 JVM が稼動し続けていると大抵は Tenured 領域もオブジェクトでいっぱいになります。その中
には閾値を超えたガーベッジ・コレクションを生き延びたものの、すでにガーベッジとなってしまっている
オブジェクトも存在します。そこで Tenured 領域に対してもガーベッジ・コレクションが実施されます。
tenured 領域のガーベッジ・コレクションは Optimize for Pause Time と同じ方式がとられています。これに
より Tenured 領域のガーベッジ・コレクションにかかる時間を短縮します。GC ポリシー名に「Concurrent」
とついているのはこの Tenured 領域に採用されたガーベッジ・コレクションの性質を表しているためで
す。
なお、Scavenge 以外のコレクション、すなわち Mark-Sweep タイプのコレクションは Global コレクションと
いう名称がつけられており、Scavenge および Glabal の名称は verbosegc ログの出力にも使用されていま
す。
以下に Generational Concurrent 適用時のスレッドの稼動イメージを示します。Nursery 領域を対象とした
Scavenge コレクションと、Tenured 領域を対象とした Concurrent トレースと Glocal コレクションが混在しま
す。
スレッド1
スレッド2
スレッド3
…
スレッドn
時間
アプリケーション処理
Scavengeコレクション
Globalコレクション
実施中は
アプリケーション処理停止
Concurrentトレース
図 2-40 アプリケーション・スレッドとガーベッジ・コレクションの関係(Generational Concurrent)
(参考)TenuredAge
オブジェクトの「年齢」はどれだけの回数のガーベッジ・コレクションを生き延びたかで判断されます。
Scavenge コレクションが実施されるたびに、JVM は生き残ったオブジェクトにひとつずつ「年齢」を加算
して管理を継続していきます。tenured 領域へは閾値の回数だけ生き延びたオブジェクトのみが移動す
ることができますが、この閾値は最大でも 14 です(つまり、タイムアウトをある程度長く設定した
HTTPSession オブジェクトやデータ・ソースの Connection オブジェクトなどは最終的に Tenured 領域に格
納される可能性が高くなります)。この閾値は Nursery 領域内にとどまっているオブジェクトの割合によっ
て JVM が調整を行っていて、生き延びているオブジェクトの占有率が 10%以下の場合閾値は 10 に、そ
の後占有率の上昇とともに閾値も上がっていき、占有率が 30%を超えると最大値に到達します。
(参考)Nursery 領域の動的拡張
Generational Concurrent では Nursery 領域と Tenured 領域の両方のサイズを動的に変更することができ
ます。最高のパフォーマンスを発揮させるための最適な Nursery 領域のサイズはその時々によって変わ
ってくるため、JVM 汎用引数で明示的に固定する設定を取っていない限り、JVM はその時々に応じて
ある期間の GC 総時間と GC の頻度からサイズ拡張または収縮を行います。
(参考)Tiltratio
Nursery コレクションの実施間隔は tilting と呼ばれる技術によって最適化されています。これは生き残っ
ているオブジェクトの総量に応じて Allocate 領域と Survivor 領域の割合を変更していきます。最初は
50%ずつから始まりますが、オブジェクトが蓄積されていくにつれて JVM は Survivor 領域が小さくなるよ
うに割合を変更していきます。これによって無駄なヒープ領域をなるべく減らし、結果として Nursery コレ
クションの実施間隔が長くなります。
(参考)Remembered Set と Write Barriers
一般論として、Generational Concurrent を適用している場合、Write Barrier と呼ばれる作業がパフォーマ
ンスを低下させる要素としてあります。Write Barrier とは、Tenured 領域上のオブジェクトに何らかの更新
作業が入ると、当該オブジェクトが Nursery 領域に存在するオブジェクトをポイントしていないことをチェッ
クするする作業のことを言います。もし Nursery 領域上のオブジェクトをポイントしている場合、Scavenge
コレクションが起こるたびにポイント先オブジェクトのアドレス情報が変わります。そのため、JVM は
Remembered set と呼ばれるコンポーネントに当該オブジェクト情報を記憶しておき、ガーベッジ・コレクシ
ョンが実施される度にステータス情報の更新が行われます。通常は Nursery 領域のオブジェクトをポイン
トしている Tenured 領域内のオブジェクトはそれほど多くないことや、J9 VM では Write Barrier のロジック
の最適化を行っているため、パフォーマンス低下があまり起こらないようになっています。
2-3-4-6 Subpooling(-Xgcpolicy:subpool)
これまで挙げた三つの GC ポリシーを適用するケースでは、適切なガーベッジ・コレクションのアルゴリズ
ムを採用することで最適なパフォーマンスを得ることを目的としています。それに対して、これから紹介す
る Subpool ポリシーの適用ではオブジェクトのヒープへの割り当て、つまりヒープ・アロケーションのアルゴ
リズムを変更することで適切なパフォーマンスを得ることを目的とします。この GC ポリシーを適用するに
は POWER アーキテクチャーの CPU を利用したプラットフォームであることが必要条件です。また、一般
に 8way 以上のシステムでの並列稼動を実施する場合に当 GC ポリシーの効果が期待できると言われて
います。
ヒープのレイアウトやガーベッジ・コレクションの方式はデフォルトの Optimize for Throughput とまったく
同じです。違いは、ヒープの空き領域を管理する Free list がデフォルトではヒープ全体でひとつであった
のに対して、この GC ポリシーを適用すると(名前にもある)Subpool と呼ばれる複数の Free list で管理を
行うところにあります。それぞれ Subpool は以下のようにある大きさを持った空き領域(チャンク)が紐付け
られていて、条件にあったサイズのオブジェクト割り当て要求がくると適当な Subpool から割り当てを行い
ます。これによってデフォルトの Optimize for Throughput のように Free list 内のチャンクを最初から検索
する必要がなく、複数の Free list が利用できるのでヒープ・アロケーションによって発生するロックの頻度
を下げることもできるため、パフォーマンス効率の高いアロケーションが実施できます。今説明したよう
に、このポリシーは沢山の CPU で稼動している JVM のヒープ・アロケーションによるロック待ちなどによる
パフォーマンス低下を回避するためのものであるため、沢山の CPU を搭載していないシステムでは実施
しても意味がありません。多くの CPU で稼動している場合は逆にこのポリシーを適用しないと沢山 CPU
を積んでいるにも関わらず期待したパフォーマンスが出ないという状況も発生する可能性がでてきま
す。
なお、この GC ポリシーが適用できないプラットフォームでヒープ・アロケーションの最適化を検討したい
場 合 は 、 Generational Concurrent を 利 用 す る こ と が 代 替 策 と し て 利 用 で き る 場 合 が あ り ま す 。
Generational Concurrent では、Nursery 領域のヒープの利用方法を見ればわかるように、Free list で管理
する必要がそもそもなく、アドレスの端から順々にオブジェクトを配置していく仕組みになっているためで
す。
2-3-4-7 Java ヒープ・サイズのチューニング
ヒープサイズを適切に設定しておくことは JVM が適切なパフォーマンスを発揮する上で非常に重要で
す。設定したヒープサイズが実際の必要量よりも少ないと Allocation Failure が相対的に多く発生します
のでガーベッジ・コレクションの実施頻度が上がりますし、最悪の場合メモリ不足エラー(OutOfMemory)
が発生してプロセスの稼動そのものができなくなる可能性も出てきます。また逆に大きすぎるヒープサイ
ズを設定すると、ガーベッジ・コレクションの実施時間が長くなります。OS から割り当て可能なサイズを超
えて設定をしてしまうと、ページングが発生する恐れが出てきます。
ヒープサイズを調整する際は一般に二通りの考え方があります。
1. ヒープサイズを JVM に動的に変更できるように設定する: Generatianal Concurrent 以外の GC ポリシ
ーを適用している場合、最小ヒープサイズを最大ヒープサイズよりも大きくすることで、差分の範囲で
JVM がヒープサイズ調整のアルゴリズムの則って動的にヒープを変更できるようになります。また、
Generatianal Concurrent GC ポリシーを適用している場合は全体の最大サイズを決めておけば、JVM
が両方の領域のサイズをヒープサイズ調整のアルゴリズムの則って動的に変更できるようになります
2. ヒープサイズを固定する(JVM に調整を任せない): Generatianal Concurrent 以外の GC ポリシーを適
用している場合、最小ヒープサイズと最大ヒープサイズを同じ値にすることでサイズが固定されます。
また、Generatianal Concurrent GC ポリシーを適用している場合は Nursery 領域または Tenured 領域の
サイズを指定することで両方の領域のサイズが固定されます
ヒープサイズの一般的な設定指針
ヒープサイズの決定においては、必要とするタイミングで必要な量だけのヒープを WAS(JVM)が確保で
きるように必要十分なサイズを確保することが重要です。逆にこれができていないとガーベッジ・コレクシ
ジ・コレクシ
ョンが必要以上に発生したり、メモリ不足エラーが発生するなどしてパフォーマンスや稼動そのものに影
響が出てきます。
WAS が Java ヒープを使用して保管するオブジェクトを、オブジェクト割り当ての発生タイミングという観点
でグループ化すると以下の図のようになります(なお、図中のグループ名称は便宜的につけたもので、
実際にこのような名称で呼ばれているわけではありません)。
この図の中で WAS の初期時に必ず必要になるコア部分にあたる Application Footprint 1 と WAS
Footprint 1 の和を最小ヒープサイズに設定すると、初期化時に不要なヒープ拡張が発生することを回避
でき、起動パフォーマンスを向上させることができます。初期(最小)ヒープサイズ設定値を決定する際
は、verbosegc ログ(後述)を有効にしたうえで WAS の起動直後にどのくらいヒープが必要になっている
のかを確認することでおおよその値を決定することができます。
Application Footprint
2
• 稼動環境(アクセス数など)に依存(変動)
• オブジェクト(ex. 結果セットなどの一時利用変数)
• アプリのコア部分(固定)
• アプリケーションクラス
• 前提リソース
(ex. フレームワーク)
など
Application Footprint
1
WAS Footprint
2
• WASのコア部分(固定)
• WASランタイム
• XMLパーサー
• ORB
• JMX
• セキュリティAPI
• クラスローダー
など
図 2-41
WAS Footprint
1
WAS のメモリ・フットプリント概略
• HTTPセッション
• dynacache
• 各種リソース
• ユーザー設定に依存(変動)
• 各種スレッドプール
• 接続プール
• 各種キャッシュ
• Prepared statement
• EJBのキャッシュ など
• 各種ログ
など
WAS が起動した後、実際にリクエスト処理を行なっていくと、処理に必要なオブジェクトが適宜ロードさ
れていきます。図の WAS Footprint 2 や Application Footprint 2 の中に分類しているものが該当します。
スレッドプールや接続プールなど、WAS の設定パラメータに多く依存する WAS Foortprint 2 の部分はテ
ストフェーズにて実際に負荷をかけ、実際に最大数をロードしたタイミングでの verbosegc ログから必要な
サイズの見積もりを行ないます。
Application Footprint 2 に分類されるオブジェクトの総サイズは稼動中のタイミングと条件によって大きく
変わってきます。HTTP セッション・オブジェクトを例にとると、セッションを有効にしている状況では WAS
に入ってくるリクエストの数に比例してオブジェクトが生成されますし、各オブジェクトのサイズもユーザー
の画面遷移やアクションによって変わってきます。そのためこの部分の見積もりについては、事前にアプ
リケーション・サーバーの 1 プロセスあたりどのくらいのリクエスト受付を受容するかなどを決定した上で
負荷テストを行ない、適切なサイズを決定するのが望ましいと言えます。
Generatianal Concurrent以外のGCポリシー適用時のチューニング
Generational Concurrent を GC ポリシーとして設定してない場合、ヒープは Mark&Sweep 方式による
Global コレクションが実施される領域と言い換えることができ、ヒープは JVM 内にひとつの領域として存
在ます。設定できる箇所は初期ヒープサイズ(これが最小値となります)と最大ヒープサイズとなり、それぞ
れ-Xms,-Xmx の引数を JVM 初期化時に渡すことで設定できます。
設定例
システムの稼動状態にあわせて、ヒープサイズを JVM に動的に変更させることを許可する場合、最大ヒ
ープサイズを初期ヒープサイズよりも大きく設定します。また、ヒープサイズを固定する場合は初期ヒープ
サイズと最大ヒープサイズの大きさを同じにします。
ヒープサイズ可変
-XmsAm –XmxBm
0
A
B
ヒープサイズ固定
-XmsBm –XmxBm
0
B
図 2-42 デフォルト型のヒープサイズ設定
以下にいくつか具体例を示します。なお、WAS におけるヒープサイズの設定は例のように汎用 JVM 引
数に設定を記述してもよいですし、管理コンソールの該当するサイズ入力欄に記入してもどちらでもかま
いません。
-Xgcpolicy:optthruput –Xmx768m
このケースではデフォルトの GC ポリシーである Optimize for Throughput を採用し、最大ヒープサイズを
768MB に指定しています。初期ヒープサイズは明示的な指定が行われていませんので、JVM 初期化
時には、デフォルトの初期ヒープサイズが確保されます。デフォルトの初期ヒープサイズは稼動プラットフ
ォームによって異なり、例えば分散系の 32bit 環境では 50MB となります。初期化プロセスやリクエスト処
理等によって初期ヒープサイズでは足りなくなると、JVM は 768MB を上限として適宜ヒープの拡張を行
います。大抵の場合、WAS を起動するのに初期ヒープサイズでは足りませんので、ヒープ拡張が入るこ
とでサーバ起動時間が長くなる可能性がありますので、WAS の起動時に必要とするヒープサイズを初期
ヒープサイズとして設定しておくとよいでしょう。なお、Optimize for Throughput はデフォルトの GC ポリシ
ーですので-Xgcpolicy: optthruput の記述は行わなくても構いませんが、この例のようにどの GC ポリシー
を使用しているかを明示的に指定しても問題ありません。
-Xgcpolicy:subpool –Xms768m –Xmx1024m
このケースでは Subpooling ポリシーを適用して、WAS 初期化時にヒープサイズを 768MB に指定してい
ます。JVM は必要に応じて 1024MB までヒープサイズを拡張することが可能です。WAS 上の業務アプリ
ケーションが時間帯によって利用状況に変化がある場合は、このケースのように最小値と最大値に差を
つけておくとあまり使用されていない時にはマシンメモリの節約を行って、他のワークにメモリリソースを
渡すことができます。
-Xgcpolicy:optavgpause –Xms1024m –Xmx1024m
このケースでは Optimize for Pause Time ポリシーを使用し、ヒープサイズを常に 1024MB 確保するように
設定しています。初期ヒープサイズと最大ヒープサイズを同じ大きさにしているため、WAS の利用率が高
くても低くても、JVM によるヒープの拡張や収縮は行われません。
Generatianal Concurrent GCポリシー適用時のチューニング
Global コレクションが行われるヒープの設定は、ヒープが複数に分かれていないため、先に挙げたとおり
初期化時のサイズと最大サイズを決めるだけで、あとは JVM に運用を任せることができました。これに対
して、J9 VM から新たに採用された Generational Concurrent ではヒープを複数の領域に分けて管理して
いるため、設定がこれまでよりも複雑になっています。こちらでも、主にガーベッジ・コレクションが行われ
る Nursery 領域の使い方によって、設定に二つの方針があります。
1. Nursery 領域を小さく設定する: 主にガーベッジ・コレクションが行われる領域を小さくすることでガー
ベッジ・コレクションの頻度が上がりますが、Scavenge コレクション一回あたりの実施時間を短くするこ
とができます。そのため nursery 領域を大きく設定したときと比べるとレスポンス・タイムが向上します。
この設定方針は Tenured 領域へのオブジェクトのコピーが頻繁に起こるようなアプリケーションを稼動
する場合にはお勧めしません。
2. Nursery 領域を大きく設定する: ガーベッジ・コレクションの頻度が上記方針に比べると低くなるた
め、スループットが相対的に向上しますただし、Scavenge コレクション一回あたりの実施時間は長くな
ります。
設定例
Generational Concurrent を採用した場合のヒープは、Nursery、Tenured の各領域、および二つを合わせた
全体のヒープ領域の三つの設定ポイントがあります。このうち Nursery+Tenured 領域からなる全体のヒープ
領域の設定には Global コレクションの領域を定めたときと同じ-Xms、-Xmx を使用します。Nursery 領域の
設定は別名である new 領域のアルファベットの最初の n をとって、サイズを固定とする場合は-Xmn、動的
に変更を許可する場合の初期値は-Xmns、最大値は-Xmnx で指定します。Tenured 領域も同様に別名の
old 領域の頭文字をとって、固定とする場合は-Xmo を、動的に変更を許可する場合は-Xmos、-Xmox で
指定します。
以下に設定例を出しますが、ポイントはそれぞれの領域で明示的に固定値、ないしは{初期値、最大値}
のペアを指定しないと、稼動中に JVM が動的にサイズを変更するということです。
Nursery領域 + Tenured領域
-XmsAm –XmxBm
0
B
A
図 2-43 Generational Concurrent のヒープサイズ設定例:
全体の最小サイズ・最大サイズのみを指定するケース
Nursery領域
Tenured領域
-XmnAm
-XmoBm
0
図 2-44
A
B
0
Generational Concurrent のヒープサイズ設定例:
Nursery 領域と Tenured 領域のサイズを固定するケース
Nursery領域
Tenured領域
-XmnsAm –XmnxBm
0
図 2-45
A
-XmosCm –XmoxDm
B
0
C
Generational Concurrent のヒープサイズ設定例:
Nursery 領域および Tenured 領域ともに動的な変更を許可するケース
D
-Xgcpolicy:gencon –Xms768m –Xmx1024m
このケースでは全体のヒープサイズの初期値、最大値のみを指定して、Nursery および Tenured 領域への
配分を JVM に動的に変更させる設定となります。ただし、ここで一点考慮点があります。Nursery 領域は
最大サイズを指定していない場合、64MB 以上には拡張されません。そのため、このケースでは Tenured
領域のみが 1024MB – (Nursery 領域のサイズ) を上限に拡張することができます。
-Xgcpolicy:gencon –Xmns64m -Xmnx256m -Xmx1024m
このケースでは Nursery 領域の初期サイズが 64MB で、最大 256MB まで拡張が可能です。また Tenured
領域は最大で 1024MB – (Nursery 領域のサイズ) まで拡張が可能になります。
-Xgcpolicy:gencon –Xmn128m -Xmx1024m
このケースでは Nursery 領域を 128MB で固定しています。Nursery を固定しているので、Tenured 領域は
最大 1024 – 128 = 896MB まで拡張が可能になります。
-Xgcpolicy:gencon –Xmns128m –Xmnx512m –Xmo512m –Xmx1024m
このケースでは Nursery 領域を初期値 128MB とし、最大 512MB までの拡張を許可しています。また
tenured 領域は 512MB 固定しています。両方の領域の最大サイズがわかっているので、最後についてい
る全体サイズの最大値を指定している-Xmx1024m の入力は必ずしも必要ではありません。ただし、最大
どれくらいの割り当てを行えるかをわかりやすくしておくためにこのように明示しておいても問題はありませ
ん。
2-3-4-8 Javaヒープ・サイズの設定
WAS の Java ヒープ・サイズの設定は管理コンソールから可能です。[サーバー]→[アプリケーション・サ
ーバー]→[ApplicationServer_name]→[サーバー・インフラストラクチャー]→[Java およびプロセス管理]
→[プロセス定義]→[追加プロパティ]→[Java 仮想マシン] を選択して、Java 仮想マシンの設定ページ
を表示します。
図 2-46 Java 仮想マシン設定
[初期ヒープ・サイズ]フィールドでは、JVM が起動時に確保するメモリー領域のサイズ(-Xms)を指定しま
す。
[最大ヒープ・サイズ]フィールドでは JVM が確保できるメモリー領域の最大サイズ(-Xmx)を指定します。
[汎用 JVM 引数]フィールドでは JVM が起動時に読み込む引数を指定することができます。この欄に
-Xms, -Xmx 引数でヒープサイズを指定することもできます。Generational Concurrent ポリシー適用時で、
Nursery/Tenured 領域の設定を行なう場合は他に設定欄がありませんので、汎用 JVM 引数に設定しま
す。
2-4 モニタリング・ツール
パフォーマンス・チューニングを実施するにあたり、システムのどの部分がボトルネックとなっていて、
チューニングが必要なのかを見極めなければなりません。この節ではチューニングを実施する前段階と
して行うモニタリングについて、主要なモニタリング・ポイントと使用するモニタリング・ツールの使用方法
を説明します。最後には、モニタリングの結果の解析について述べます。
2-4-1 Performance Monitoring Infrastructure
WAS ではパフォーマンス・データを取得するために PMI というフレームワークを使用します。ここでは
PMI とその設定方法について説明します。
2-4-1-1 概要
WAS ではアプリケーション・サーバーのパフォーマンス・データを取得するフレームワークとして PMI
(Performance Monitoring Infrastracture)を提供しています。WAS では各リソースの様々なパフォーマン
スデータを MBean(Managed Bean)という特別な JavaBean に格納しており、PMI はこの MBean と通信し
て各コンポーネントの必要なパフォーマンスデータを取得します。パフォーマンス・データを格納してい
る MBean は複数あり、それぞれ固有のデータを持っています。MBean には J2EE の仕様に定義されて
いる J2EE 管理対象オブジェクトの MBeans と WebSphere PMI Perf MBean があります。J2EE MBeans
は特定のコンポーネントに関するパフォーマンス・データを提供し、Perf MBean は WebSphere PMI サー
ビスへのゲートウェイとして機能し、すべてのコンポーネントに対するパフォーマンス・データにアクセス
します。
PMI
ノード
JVMヒープ使用率、JDBC接続プール数
Webコンテナースレッド使用率、セッショ
ン作成数、GC発生率・・・・・
プラグイン
Web
サーバー
MBean
MBean
MBean
MBean
MBean
MBean
MBean
MBean
MBean
アプリケーション・サーバー
DB
PMI を使用してパフォ-マンス・データを取得するモニターツールとして、Tivoli Performance Viewer(以
下、TPV)、パフォーマンス・サーブレット、PMI クライアント API があります。これらを使用して、PMI が
取得したパフォーマンスの統計データを取得することができます。
Tivoli Performance Viewer は WAS の管理コンソールに組み込まれているパフォーマンス・モニター・ツ
ールです。パフォーマンス・サーブレットは、パフォーマンス・データを XML 形式で出力するサーブレッ
トでこちらも WAS で提供されています。PMI クライアント API を使用して独自のモニター・アプリケーシ
ョンの開発が可能ですが、WAS V6.1 では推奨されていません。独自のモニター・アプリケーションの開
発には JMX の使用が推奨されています。
2-4-1-2 モニターできるデータ
パフォーマンス・データは、それぞれのコンポーネントに対応したモジュールというカテゴリーでグルー
プ化されています。モジュールには以下のものがあります。
-Enterprise Bean
-JDBC 接続プール
-J2C 接続プール
-Java 仮想マシン(JVM)
-オブジェクト・リクエスト・ブローカー(ORB)
-サーブレット・セッション
-トランザクション
-スレッド・プール
-Web アプリケーション
-ワークロード管理(WLM)
-システム
-動的キャッシュ
-Web サービス・ゲートウェイ(WSGW)
-Web サービス
-Alarm Manager
-オブジェクト・プール
-スケジューラー
-高可用性マネージャー(HA マネージャー)
-DCS スタック
-システム統合バス(SIB)およびメッセージング
2-4-1-3 PMI設定
PMI を使用してパフォーマンス・データを収集するためには、管理コンソールによって PMI を使用可
能にする必要があります。(WAS V6.1 では PMI はデフォルトで使用可能になっています。)管理コンソ
ー ル よ り [ モ ニ タ ー お よ び チ ュ ー ニ ン グ ] → [Performance Monitoring Infrastructure (PMI)] →
[AppServer_name]を選択して、構成タブの[Performance Monitoring Infrastructure (PMI)を使用可
能にする]にチェックを付けると PMI は使用可能になります。設定変更後はアプリケーション・サーバーを
再始動する必要があります。
モニターできるパフォーマンス・データは統計のセットとして、表 2-3に示す4つの定義済みの統計セット
が提供されています。定義済みの統計セットの他に[カスタム]のリンクをクリックして、モニターするパフォ
ーマンス・データを選択することが可能です。デフォルトで[基本]となっているため、より多くのパフォー
マンス・データをモニターするためには、[現在モニターされている統計セット]で[なし]、[基本]、[拡張]、
[すべて]、[カスタム]のいずれかにチェックを付けて、適切な統計セットを設定します。統計セットの変更
後はアプリケーション・サーバーを再始動する必要があります。
図 2-47 PMI 設定
統計セット
なし
基本
拡張
すべて
カスタム
説明
すべての統計を使用不可にします。
ランタイムおよびアプリケーション・コンポーネントに関する基本的なパフォーマンス・デー
タを提供します。J2EE1.4 で指定された統計および CPU や HTTP セッションなどの基本的
な統計が使用可能になります。デフォルトの統計セットに設定されています。
ランタイムおよびアプリケーション・コンポーネントに関する詳細なパフォーマンス・データ
を提供します。WAS コンポーネントの基本セットおよびキー統計が使用可能になります。
すべての統計が使用可能になります。
統計を選択して、モジュールごとに使用可能または使用不可に設定します。
表 2-3 統計セット
2-4-2 Tivoli Performance Viewer
Tivoli Performance Viewer(以下、TPV)は管理コンソールに組み込まれた WAS のパフォーマンス・モ
ニタリング・ツールです。TPV を使用することによって、管理コンソールから WAS の各リソースの状況を
モニターすることができます。
2-4-2-1 モニターの開始
WAS の現在のリソース状況のモニター方法を説明します。TPV ではノード上のすべてのアプリケーシ
ョン・サーバーとノード・エージェントがモニター対象となります。
①
管理コンソールより[モニターおよびチューニング]→[Performance Viewer]→[現行アクティビティ]
を選択するとアプリケーション・サーバーとノード・エージェントの一覧が表示されるので、モニター
の対象のアプリケーション・サーバー、またはノード・エージェントにチェックボックスにチェックを付
けて、[モニターの開始]ボタンを押します。[コレクション状況]が[使用可能]から[モニター対象]に
変更することで、モニター開始が確認できます。この時点からパフォーマンス・データの収集が開
始します。
図 2-48 モニターの開始
②
モニター対象のアプリケーション・サーバー、またはノード・エージェントのリンクをクリックすると
TPV コンソール・パネルが表示され、左側にナビゲーション・ツリー、右側に現行のパフォーマン
ス・アクティビティのリアルタイムのデータが表示されます。
2-4-2-2 ユーザー設定およびロギング設定
TPV のモニターでは以下のユーザー設定およびロギング設定が可能です。
ユーザー設定
ユーザー設定では収集するパフォーマンス・データに関する以下の値の設定を必要に応じて行いま
す。TPV コンソール・パネルのナビゲーション・ツリーより[設定]→[ユーザー]を選択し[ユーザー設定]ペ
ージを表示します。
リフレッシュ速度
パフォーマンス・データを収集する間隔を秒単位で指定します。デフォルトでは30秒です。指定可能な
数値は5秒から500秒です。
バッファーサイズ
収集したデータを一時的に保管する際のデータ量を指定します。TPV で表示されるデータは、メモリー
内のバッファーに 保管されるため、バッファーがフルになった後は、古いデータから破棄されていきま
す。デフォルトのバッファーサイズは40です。指定可能な値は10から100です。バッファー・サイズが大
きいとそれだけ、メモリーを消費するので適切な設定をする必要があります。
データ表示
収集したデータの表示方法を設定します。以下の選択が可能です。
−
生データ:収集したデータの絶対値を表示します。
−
値の変化:直前の値と現行までの値の変化を表示します。
−
変化率:値の変化を時間で割った値を表示します。
図 2-49 ユーザー設定
ロギング設定
ロギング設定ではロギングに関する以下の設定を行います。
期間
[ロギング開始]をしてから[ロギング停止]を行わない限り、ロギングを継続する時間を設定します。デフォ
ルトでは20分です。
最大ファイルサイズ
ひとつのログ・ファイルのサイズを指定します。TPV ではログ・ファイルを自動で ZIP 形式に圧縮します
が、このパラメーターは圧縮前のファイル・サイズの指定となります。
ヒストリー・ファイルの最大数
ログ・ファイルは循環ログとなっているため、TPV が書き込むファイルの最大数を指定します。
ファイル名
ログ・ファイルのプレフィックスを指定します。実際のファイル名は以下のようになります。
<prefix>_<process_name>_<timestamp>_<suffix_number>.zip
ログ出力フォーマット
ログ・ファイルのフォーマットを XML もしくはバイナリーに指定します。バイナリーの方がログ・ファイルの
解凍後のファイル・サイズは小さくなります。
図 2-50 ロギング設定
2-4-2-3 現行アクティビティの表示(パフォーマンス・モジュール)
TPV コンソール・パネルのナビゲーション・ツリーの[パフォーマンス・モジュール]を展開すると、TPV
で取得できる WAS のモニター項目が表示されます。チェック・ボックスにチェックを付けたモニター項目
についてビューアーに表示されます。[モジュールの表示]ボタンを押すことで、ビューアーにグラフ表示
されます。(PMI は指定したレベルの全データを取得していますが、ビューアーに表示されるのはチェッ
クを付けたモニター項目のみです。)
図 2-51 現行アクティビティの表示
ビューアーにおけるデータ表示
•
グラフの表示
取得データを図 2-51のようにグラフ表示
•
表の表示
取得データを表形式で表示
•
バッファーのクリア
表、またはグラフ形式で現在ビューアーに表示されている値を削除します。データ取得の停止後
に実施すると、ビューアー上のデータが削除されます。
•
ゼロにリセット
取得されるデータには、取得開始からの相対値を表すデータと、取得時のリアルタイムでの値を
表すデータがあります。データが相対値である場合、この操作によってデータはゼロにリセットさ
れ操作時点を開始時刻としてデータの表示が再開されます。データがリアルタイムの状態を表す
ロード・データである場合、リセットはできないので影響はありません。この操作を行うと、[バッファ
ーのクリア]での操作も同時に行われます。
•
名前
グラフのマーカーに対応する値については、ビューアー下に表形式で表示されます。[名前]にカ
ーソルを当てると値の説明を確認することができます。
•
尺度
グラフに表示する値の倍率を設定することができます。実際の値に[尺度]を乗じた値(「尺度の
値」)がグラフに表示されます。
2-4-2-4 モニタリング・ポイント
Web システムにおいてパフォーマンスを考慮する場合の主要なモニタリング・ポイントとして以下の図
に示す 10 項目がありますが、ほとんどの項目については Tivoli Performance Viewer を使用してモニタ
ーすることができます。これらの主要モニタリング・ポイントについて Tivoli Performance Viewer のどのパ
フォーマンス・モジュールでモニターしていくのかについて説明します。
図 2-52 Web システムにおけるモニタリング・ポイント
1). 平均応答時間
サ ー ブ レ ッ ト の 平 均 応 答 時 間 は パ フ ォ ー マ ン ス ・ モ ジ ュ ー ル [Web ア プ リ ケ ー シ ョ ン ] の
[ServiceTime]で Web コンテナー上のサーブレットの平均値をモニターすることができます。
2). スループット
スループットはパフォーマンス・モジュール[Web アプリケーション]の[RequestCount]でモニター
することができます。以下の表に、[Web アプリケーション]で取得できるデータを示します。
名前
統計セット
説明
Loaded Servlet Count
すべて
ロードされたサーブレットの数
Reload Count
すべて
再ロードされたサーブレットの数
Request Count
基本
1つのサーブレットが処理したリクエストの合計数
Concurrent Requests
拡張
同時に処理されるリクエスト数
Service Time
基本
サーブレットのリクエストが終了する平均応答時間(ミリ秒)
Error Count
拡張
サーブレットと JSP ファイルにおけるエラーの総数
3). HTTP セッション数
HTTPセッションオブジェクト数はパフォーマンス・モジュール[サーブレット・セッション・マネージャ
ー]の[LiveCount]でモニターすることができます。HTTP セッションについてはその他にも、以下
の表に示すデータを[サーブレット・セッション・マネージャー]でモニターすることができます。
名前
統計セット
説明
CreateCount
すべて
作成されたセッションの合計数
InvalidateCount
すべて
無効になったセッションの合計数
LifeTime
拡張
セッションの平均存続時間(ミリ秒)
ActiveCount
すべて
同時にアクティブなセッション数。WASがセッションを使用す
るリクエストを処理している場合、セッションはアクティブ とな
る。
LiveCount
拡張
メモリー内にあるセッション数
NoRoomForNewSessi
拡張
「オーバーフローの許可」がチェックされていない際に適用。新
規セッションの要求を処理できない合計回数。
onCount
CacheDiscardCount
すべて
分散セッションでキャッシュから破棄されたセッションの合計数
ExternalReadTime
拡張
分散セッションで、外部からセッション・オブジェクトを読み取る
のにかかった時間(ミリ秒)
ExternalReadSize
拡張
分散セッションで、外部から読み取ったセッション・オブジェクト
のサイズ
ExternalWriteTime
拡張
分散セッションで、外部にセッション・オブジェクトを書き込むの
にかかった時間(ミリ秒)
ExternalWriteSize
拡張
分散セッションで、外部に書き込んだセッション・オブジェクトの
サイズ
AffinityBreakCount
すべて
フェイル・オーバーなどで中断されたアフィニティの合計数
TimeSinceLastActivate
すべて
セッション・オブジェクトに対してのアクセス間隔の平均時間(ミ
リ秒)
d
TimeoutInvalidationCo
すべて
未使用のセッションがタイムアウトで無効になった合計数
すべて
タイムアウトが原因で存在していないセッションに対するリクエ
unt
ActivateNonExistSessi
ストの合計数
onCount
SessionObjectSize
すべて
メモリー内のシリアライズ化されたセッション・オブジェクトのサ
イズ
4). Web サーバー・スレッド
Web サーバー・スレッドのモニタリングは、Tivoli Performance Viewer ではできません。「4-3-2-2
IBM HTTP Server のモニタリング」を参照してください。
5). スレッド・プール
Webコンテナー・スレッド・プール:
Web コンテナー・スレッド・プールの情報はパフォーマン
ス・モジュール[スレッド・プール]→[WebContainer]でモニターすることができます。
ORBスレッド・プール:
ORB スレッド・プールの情報はパフォーマンス・モジュール[スレッド・プ
ール]→[オブジェクト・リクエスト・ブローカー]でモニターすることができます。
各スレッド・プールについて取得可能なデータは同じになります。以下の表に、[スレッド・プール]
でモニターできるスレッド・プールのデータを示します。
名前
統計セット
説明
CreateCount
すべて
作成されたスレッドの合計数
DestroyCount
すべて
破棄されたスレッドの合計数
ActiveCount
拡張
同時にアクティブなスレッドの数とその平均値
PoolSize
基本
プール内のスレッドの数とその平均値
PercentMaxed
すべて
プール内のすべてのスレッドが使用中である時間の平均比率
(%)
DeclaredThreadHung
すべて
停止宣言されたスレッドの総数
すべて
クリアされた停止スレッド数
すべて
同時に停止したスレッド数
すべて
スレッドがアクティブな状態である平均時間(ミリ秒)
Count
ClearedThreadHungC
ount
ConcurrentHungThrea
dCount
ActiveTime
6). データ・ソース接続プール
アプリケーションでデータ・ソースを使用してデータベースへの JDBC 接続を行っている場合に、
データ・ソースごとに接続プールの情報をモニターすることができます。
パフォーマンス・モジュール[JDBC 接続プール]→[JDBCProvider_name]→[JNDI_name]でモ
ニターするデータ・ソースの JNDI 名にチェックを付けます。
以下の表に、[JDBC 接続プール]でモニターできる接続プールのデータを示します。
名前
統計セット
説明
CreateCount
基本
getConnection()によってプールに作成された接続数の合計
CloseCount
基本
保守スレッドサービスによってプールから破棄された接続数の
合計
AllocateCount
すべて
getConnection()によって 使用されたプール内の接続数の合
計
ReturnCount
すべて
close()によって未使用になったプール内の接続数の合計
PoolSize
基本
プールにある接続数
FreePoolSize
基本
プールにある空き接続数
WaitingThreadCount
基本
プール内に使用可能な接続がなく同時に接続待ちをするスレ
ッド数
FaultCount
拡張
待機状態のスレッドが接続タイムアウトになる回数の合計
PercentUsed
基本
プール内の接続の使用率の平均パーセント
PercentMaxed
すべて
すべての接続が使用中である時間の平均パーセント
UseTime
基本
接続が使用される平均時間(接続が割り振られる時刻から戻
される時刻までの時間)(ミリ秒)
WaitTime
基本
接続が割り振られるまでの平均待ち時間(ミリ秒)
ManagedConnectionC
すべて
プール内の接続数(物理接続数)
すべて
getConnection()によって割り振られた接続ハンドルの数
拡張
廃棄された PreparedStatement の合計数
拡張
JDBC ドライバー内での実行にかかった時間(ミリ秒)
ount
ConnectionHandleCou
nt
PrepStmtCacheDiscar
dCount
JDBCTime
7). JVM メモリー
アプリケーション・サーバーとノード・エージェントの JVM の情報をパフォーマンス・モジュール[JVM ラン
タイム]でモニターすることができます。デフォルトでは以下の表に示すデータがモニターできますが、
JVMPI(JVM Profiler Interface)を使用可能にすることで、ガーベッジ・コレクションなどの詳細データを
モニターすることもできます。ただし、JVMPI を使用することによってパフォーマンスが低下するので注
意が必要です。
JVM ランタイム
名前
統計セット
説明
HeapSize
基本
JVM ヒープサイズ(KB)
FreeMemory
拡張
ヒープの空きメモリー・サイズ(KB)
UsedMemory
基本
ヒープの使用メモリー・サイズ(KB)
UpTime
基本
JVM が起動してからの経過時間(ミリ秒)
以下は、アプリケーション・サーバーの JVM の設定で JVMPI を使用可能にすることで、モニターするこ
とができます。
ガーベッジ・コレクション
名前
統計セット
説明
GCCount
カスタム
GCが発生した合計数
GCIntervalTime
カスタム
2 回のGC間の平均時間(ミリ秒)
GCTime
カスタム
1 回のGCが要する時間の平均(ミリ秒)
名前
統計セット
説明
WaitsForLockCount
カスタム
Java スレッドが Java モニターを待機する合計回数
WaitForLockTime
カスタム
Java スレッドが Java モニターを待機する平均時間
名前
統計セット
説明
ObjectAllocateCount
カスタム
ヒープ領域に割り当てられたオブジェクト数の合計
ObjectFreedCount
カスタム
GC によってヒープ領域から開放されたオブジェクト数の合計
ObjectMovedCount
カスタム
GC の Compaction によって移動したオブジェクト数の合計
名前
統計セット
説明
ThreadStartedCount
カスタム
開始した Java スレッド数の合計
ThreadEndedCount
カスタム
終了した Java スレッド数の合計
モニター
オブジェクト
スレッド
JVMPI(JVM Profiler Interface)の使用可能設定
JVMPI を使用可能にするためには、JVMに対しての設定が必要になります。管理コンソールから[サー
バー]→[アプリケーション・サーバー]→[ApplicationServer_name]→[サーバー・インフラストラクチャー]
→[Java およびプロセス管理]→[プロセス定義]→[追加プロパティ]→[Java 仮想マシン]を選択して、
JVM の設定画面を表示します。汎用 JVM 引数の設定フィールドに「-XrunpmiJvmpiProfiler」お入力し
て保管処理を行います。プロセスを再起動することによって、JVMPI は使用可能になります。
2-4-2-5 ロギング
Tivoli Performance Viewer(以下、TPV)のロギング処理では、取得データをログ・ファイルに出力して
残し、一定期間のリソース状況を再生することが可能です。
ログの取得
ログの取得方法を説明します。左側ツリーの上部に[モジュールの表示]ボタンを押して、ビューアーを表
示します。ビューアー上部の[ロギング開始]ボタンを押すとログの出力が開始します。ロギングを停止し
たいタイミングで[ロギング停止]ボタン押してログ出力を停止します。
ログ・ファイルの設定については「2-4-2-2ユーザー設定およびロギング設定」のロギング設定を参照して
ください。
ログの再生
ロギング処理で取得したログ・ファイルをビューアーで再生する手順を説明します。
①
管理コンソールのナビゲーション・ツリーから[モニターおよびチューニング]→[Performance
Viewer]→[ログの表示]を選択して、ログ・ファイルの選択画面を表示します。
②
[ログ・ファイルの明示的パス]にチェックをいれて、参照ボタンでログ・ファイルを選択します。
ログ・ファイルは記録中には.xml(XML フォーマット)もしくは.tpv(バイナリーフォーマット)を
拡張子に持つファイルに出力されますが、記録停止後に自動的にファイルサイズ縮小のた
めに ZIP 形式のファイルに圧縮されます。
③
[ログの表示]ボタンを押すと、ビューアーが表示され、ログの再生が開始します。
図 2-53 ログファイルの選択
④
TPV のツリーのパフォーマンス・モジュールからモニターするモジュールにチェックを付けて、
[モジュールの表示]ボタンを押すと、ビューアーにデータが表示されます。
⑤
ビューアー上部のボタンでログ・ビューの調整が可能です。ログの表示が終了するまで、ロ
グの再生が行われます。
2-4-3 パフォーマンス・アドバイザー
パフォーマンス・アドバイザーはWASでパフォーマンス・チューニングのアドバイスを通知するツール
です。パフォーマンス・アドバイザーには、Runtime Performance AdvisorとTivoli Performance Viewerで
提供されるPerformance Advisor(TPV Advisor)があります。共にPMIで取得したデータを元に、スレッド・
プール、接続プール、Prepared Statement Cache、セッション、ヒープ・サイズなどのチューニングを示唆
します。使用するにはPMIを使用可能にする必要があります。PMIはデフォルトでは使用可能になって
います。設定については2-4-1-3PMI設定(p.67)を参照してください。
Runtime Performance Advisor
Runtime Performance Advisorはアプリケーション・サーバー上で稼動し、パフォーマンスを定期的に
チェックしてパフォーマンス・チューニングに関するアドバイスを管理コンソールの[WebSphere ランタイ
ム・メッセージ]と標準出力であるSystemOut.logファイルに出力します。Runtime Performance Advisorを
使用することによるシステムへの負荷はほとんどありません。
Runtime Performance Advisor はデフォルトでは使用可能になっていません。管理コンソールから[サー
バー]→[アプリ ケーション・サーバー]→[ApplicationServer_name]→[パフォーマンス]→[Runtime
Performance Advisor 構成]を選択して Runtime Performance Advisor 構成ページを表示します。構成タ
ブの一般プロパティで[Runtime Performance Advisor を使用可能にする]のチェックボックスにチェック
を付け、[適用]または[OK]ボタンを押下し保管処理を行います。アプリケーション・サーバーを再始動す
ることで Runtime Performance Advisor は使用可能になります。ランタイムタブで設定を行った場合は、ア
プリケーション・サーバーの再始動は必要ありません。
以下のリソースに対してのアドバイスを通知します。
ORB サービス・スレッドプール
Web コンテナー・スレッドプール
接続プールサイズ
Persisted セッション・サイズおよび時間
Prepared Statement キャッシュ・サイズ
セッション・キャッシュ・サイズ
TPV Advisor
TPV AdvisorはTPV上で使用されるもので、管理コンソールでリソースの状況やアドバイスを表示しま
す。Runtime Performance Advisorによるアドバイスに加えて、動的キャッシュ、JVMヒープ・サーズなどの
アドバイスが通知されます。TPVコンソール・パネルのナビゲーション・ツリーの[アドバイザー]を選択し
てTPV Advisorを表示します。更新間隔はTPVと同様に指定することが可能です。設定方法について
は、2-4-2-2ユーザー設定およびロギング設定(p. 69 )を参照してください。
図 2-54 TPV アドバイザー
パネル上部の表では Web コンテナーと EJB コンテナーにおける要求数/秒と応答時間(ミリ秒)を表示し
ます。円グラフでは CPU の使用時間とアイドル時間のパーセンテージを表示しています。
パネル中部の表では、各スレッド・プール、接続プールの使用状況を表示します。
以下のリソースに対してのアドバイスを通知します。
ORB サービス・スレッドプール
Web コンテナー・スレッドプール
接続プールサイズ
Persisted セッションサイズおよび時間
Prepared Statement キャッシュ・サイズ
セッション・キャッシュ・サイズ
動的キャッシュ・サイズ
JVM ヒープ・サイズ
DB2 Performance Configuration Wizard
2-4-4 要求メトリック
Performance Monitoring Infrastructure(PMI)要求メトリックは、Web コンテナー、EJBコンテナー、デー
タベースなどの主要コンポーネントにおいて経過した時間を計測し、ログに記録する機能です。リクエス
トが WAS 内でコンポーネント間の移動にかかった時間を測定することができるので、実行環境とアプリケ
ーションのパフォーマンス問題を識別するのに役立ちます。
実稼動環境での稼動を考慮し、IP アドレスまたは URI によりフィルター操作することができます。フィ
ルタリングすることでパフォーマンスの劣化を防ぐことができます。
計測対象コンポーネント
以下の中から選択したコンポーネントを対象として、リクエストが入ってから出るまでの経過時間を計測
し、ログに出力します。
−
Web サーバー・プラグイン
−
Web コンテナー
−
EJBコンテナー
−
データベース
−
Web サービス
−
JMS
−
非同期 Bean
2-4-4-1 基本使用方法
要求メトリックの基本的な使用方法についての手順を説明します。
①
管理コンソールのナビゲーション・ツリーから[モニターおよびチューニング]→[要求メトリック]
を選択して要求メトリックの設定画面を表示します。デフォルトでは要求メトリックは使用可能
になっていないので、[要求メトリックを使用可能にする]にチェックを付けて使用可能に設定
します。
②
計測対象とするコンポーネントを[計測対象コンポーネント]から選択します。Ctrl キーを使用
して複数コンポーネントの選択が可能です。
③
[要求メトリックの宛先]の[使用可能にする]にチェックを付けて、要求メトリックで取得するデ
ータのログ・ファイルへの出力をONにします。この設定を行わないとログへ出力されません
ので注意が必要です。
④
設定を終えたら、[OK]ボタンを押して、構成の保管を行います。
⑤
要求メトリックでWebサーバー・プラグインを計測対象とする際には、Webサーバー・プラグイ
ンの構成ファイルに設定が反映されます。したがって、管理コンソールからプラグインの生成
を行う必要があります。
図 2-55 要求メトリック設定
2-4-4-2 トレース・レベルの設定
トレース・レベルの設定では、要求メトリックで取得するデータの詳細レベルを設定します。以下のレ
ベルから選択します。([なし]よりも高いレベルを設定します。)
•
なし:トレースを取得しません。
•
ホップ:プロセス境界のみの計測情報を取得します。
•
パフォーマンス・デバッグ:ひとつの追加レベルの計測データを取得します。
•
デバッグ:すべてのプロセス内のサーブレットおよび EJB 呼び出しの応答時間を含む、詳細な計
測データを提供します。
2-4-4-3 フィルターの設定
要求メトリックのオプション機能としてフィルターを使用することによって、特定の箇所のみのトレースを
取得することが可能です。要求メトリックを使用すると、ログファイルに大量のデータを出力するためにパ
フォーマンスの劣化を招きかねません。フィルターを使用して、取得するデータを限定することによっ
て、パフォーマンスの劣化を防ぐことができます。
HTTPリクエストに対するフィルター
WAS が受ける HTTP リクエストに対して、「送信元 IP アドレス・フィルター」と「URI フィルター」を使用し
てフィルタリングが可能です。
•
送信元 IP アドレス・フィルター
HTTP リクエストの送信元の IP アドレスに基づいてフィルターを掛けます。
•
URI フィルター
HTTPリクエストのURIに基づいてフィルターを掛けます。
送信元 IP アドレス・フィルターと URI フィルターを両方とも設定した場合、要求メトリックでは、両方のフィ
ルター・タイプに一致する必要があります。
EJBリクエストに対するフィルター
EJB リクエストに対して、「EJB メソッド名フィルター」を使用して、フィルタリングが可能です。
•
EJB メソッド名フィルター
EJB メソッドの絶対パス名に基づいてフィルターを掛けます。
JMSフィルター
JMS リクエストに対して、キュー宛先名およびトピック宛先名に基づいてフィルターを掛けます。
例:destination=aaa:topic=bbb
Web サービス・フィルター
Web サービスのリクエストに対して、WSDL のポート名、オペレーション名、トランスポート名の組み合
わせに基づいてフィルターを掛けます。
例:wsdlPort=aaa:op=bbb:namespace=ccc
2-4-4-4 ログの解析
要求メトリックのトレース・レコードは、Web サーバー・プラグイン・ログ・ファイル(httpd_plugin.log)とア
プリケーション・サーバーの標準出力ログ・ファイル(SystemOut.log)に出力されます。
以下に出力例を示します。
http_plugin.log
[Wed
May
25
03:25:47
2005]
00000e2c
000002d0
PLUGIN:
parent:ver=1,ip=9.189.184.209,time=1116951903203,pid=3628,reqid=5,event=1
current:ver=1,ip=9.189.184.209,time=1116951903203,pid=3628,reqid=5,event=1 type=HTTP
detail=/WASSample/TableViewer elapsed=12906 bytesIn=31 bytesOut=13676
ログでは1メソ ッドの呼び出しに関するデータが1レコードに記録されています。レコードごとに parent
(親)と current(子)で構成されており、parent ではメソッドの呼び出し元のデータが、current では呼び出
された側のデータが記録されます。
以下に、サーブレットから JDBC 接続でデータベースへアクセスするサンプル・アプリケーション
「TableViewer」を実行した際に、要求メトリックが出力するデータの例を示します。
http_plugin.log
[Wed May 25 03:25:47 2005] 00000e2c 000002d0 - PLUGIN:
parent:ver=1,ip=9.189.184.209,time=1116951903203,pid=3628,reqid=5,event=1 current:ver=1,ip=9.189.184.209,time=1116951903203,pid=3628,reqid=5,event=1 type=HTTP
detail=/WASSample/TableViewer elapsed=12906 bytesIn=31 bytesOut=13676
レスポンスタイム
自分のリクエストID
12906ミリ秒
5
親のリクエストID
自分のリクエストID
3
3
親のリクエストID
SystemOut.log
5
[05/05/25 3:25:46:609 JST] 0000002a PmiRmArmWrapp I PMRM0003I:
parent:ver=1,ip=9.189.184.209,time=1116951789906,pid=3288,reqid=3,event=1 current:ver=1,ip=9.189.184.209,time=1116951789906,pid=3288,reqid=4,event=1 type=JDBC
detail=executeQuery elapsed=4234
レスポンスタイム
[05/05/25 3:25:47:141 JST] 0000002a PmiRmArmWrapp I PMRM0003I:
4234ミリ秒
parent:ver=1,ip=9.189.184.209,time=1116951903203,pid=3628,reqid=5,event=1 current:ver=1,ip=9.189.184.209,time=1116951789906,pid=3288,reqid=3,event=1 type=URI
detail=/WASSample/TableViewer elapsed=11610
レスポンスタイム
11610ミリ秒
Web サーバー・プラグインのログには「type=HTTP」のデータ、server1 のログには「 type=URI」と
「type=JDBC」のデータが表示されています。
まず、Web サーバー・プラグインのログを見ると、/WASSample/TableViewer にアクセスがあり、このときに
付加された ID が「5」です。次に。server1 のログを見ると、reqid=5から/WASSample/TableViewer にアク
セスがあり、このときに付加された ID が「3」です。reqid=3から SQL が呼び出され DB にアクセスしてい
ることがわかります。このようにして、parent データの reqid と current データの reqid によって、1リクエスト
の複数オペレーションを紐付けることができます。下図に示すように、elapsed によってレスポンス・タイム
も出力されているので、各コンポーネントの処理時間を解析することができます。
レコードに記録されている、ログ・フォーマットの各フィールドの意味は以下の通りになります。
フィールド
parent
current
ver
ip
pid
time
reqid
event
type
detail
elapsed
bytesIn
bytesOut
説明
呼び出し側(親)の識別子
呼び出された側(子)の識別子
親と子の相関関係のバージョン。親子の両者は同じ数字になります。
アプリケーション・サーバーがあるノードの IP アドレス
アプリケーション・サーバーのプロセス ID
アプリケーション・サーバーのプロセス開始時刻
要求メトリックによってリクエストに割り当てられる ID
実際のトレースを区別するために割り当てられるイベント ID
リ ク エ ス ト の タ イ プ で 、 HTTP 、 URI 、 EJB 、 JDBC 、 JMS 、 非 同 期 ビ ー ン
(COMMONJ_WORK_POOLED、COMMONJ_TIMER)、Web サービス(要求者、プロバ
イダー)がサポートされています。
リクエストの詳細データで、URI のフルパス、SQL ステートメント、EJB メソッド名などになり
ます。
トータルの経過時間(ミリ秒)で、子の経過時間を全て含んだ時間です。
Web サーバー・プラグインが受け取ったリクエストのバイト数
Web サーバー・プラグインからクライアントに送信されたレスポンスのバイト数
type フィールドおよび detail フィールドの説明は以下のとおりです。
フィールド
HTTP
URI
説明
Web サーバー・プラグインが生成するトレース・レコードです。detail では、リクエストを呼
び出すとき使用される URI が記録されます。
Web コンポーネントが生成するトレース・レコードです。detail では、リクエストを呼びだ
EJB
JDBC
JMS
非同期 Bean
Web サービス
す時に使用される URI が記録されます。
Enterprise Bean の完全修飾パッケージおよびメソッド名です。
作成済みステートメントの select,update,insert,delete 値。作成されていないステートメント
の場合は、完全なステートメントが表示されることがあります。
JMS パラメーターの詳細が含まれます。
非 同 期 Bean の 名 前 を 指 定 す る 詳 細 。 非 同 期 ビ ー ン に は 2 つ の タ イ プ 、
COMMONJ_WORK_POOLED および COMMONJ_TIMER が含まれています。
Web サービス・パラメーターの詳細が含まれています。
2-4-5 verbosegc
verbosegc ログは JVM によるガーベッジ・コレクションが実施された際の詳細な実施結果を取得するこ
とのできるログです。例えば、コレクションの実施頻度や各コレクションの所要時間、開放されたヒープ領
域の大きさなどがわかりますので、問題判別時のガーベッジ・コレクションの挙動調査にも使われます。
2-4-5-1 verbosegcの設定方法
verbosegc を有効にするには JVM に-verbosegc オプションを設定します。管理コンソールから設定が
可能です。管理コンソールのナビゲーション・ツリーより[サーバー]→ [アプリケーション・サーバー]→
[ApplicationServer_name]→[サーバー・インフラストラクチャー]→[Java およびプロセス管理]→[プロセ
ス定義]→[追加プロパティ]→[Java 仮想マシン] を選択して、Java 仮想マシンの設定ページを表示し
ます。このページに冗長ガーベッジ・コレクションのチェックボックスがありますのでここにチェックを付け
ると次回アプリケーション・サーバが始動するタイミングから verbosegc ログが出力されるようになります。
デフォルトの出力先は<WAS_root>/profiles/<profile_name>/logs/native_stderr.log です。
verbosegc ログはまた、適当な JVM 汎用引数を入れることでも取得が可能です。-verbosegc を入力し
ます。設定後はアプリケーション・サーバーの再起動が必要になります。
が、-Xverbosegclog オプションを指定することによって出力先ファイルを明示的に指定することも可能で
す。
図 2-56 Java 仮想マシン設定
2-4-5-2 verbosegcの出力内容
3-3-4-7「Java ヒープサイズのチューニング」の項目で説明したように、ガーベッジ・コレクションには領域
の観点から整理すると Scavenge と Global の二つのタイプがあります。Generational Concurrent 以外の
GC ポリシーでは Global コレクションにて実施されます。さらに実施タイミングの観点から Global 領域に
おけるコレクションには Optimize for Pause Time、また Generational Concurrent のアルゴリズムを適用し
た際には Concurrent コレクションが実施されます。Concurrent コレクションは Generational Concurrent 適
用時の Tenured 領域でも実施されます。整理すると下図のようにまとめることができます。
表 2-57 各 GC ポリシーで実施されるコレクション形態
GC ポリシー
Optimize for Throughput
Optimize for Pause Time
Subpooling
Generational Concurrent
コレクション方法
Global
Concurrent および Global
Global
Scavenge ( Nursery 領域)
Concurrent および Global (Tenured 領域)
ここでは Concurrent コレクションを含めた 3 種類のコレクションが実施された際の出力内容について見て
いくことにします。
Global コレクション
まずはデフォルト GC ポリシーである Optimize for Throughput の出力例を見ていくことにします。
Subpooling ポリシーを適用している場合も同じガーベッジ・コレクションのアルゴリズムを使用しているの
で同じ出力形態をとります。
<af type="tenured" id="18" timestamp="Sun Jul 23 14:35:43 2006" intervalms="3419.274">
<minimum requested_bytes="7000" />
<time exclusiveaccessms="0.074" />
<tenured freebytes="1521448" totalbytes="1073741824" percent="0" >
<soa freebytes="447784" totalbytes="1072668160" percent="0" />
<loa freebytes="1073664" totalbytes="1073664" percent="100" />
</tenured>
<gc type="global" id="18" totalid="18" intervalms="3420.464">
<refs_cleared soft="0" weak="0" phantom="6" />
<finalization objectsqueued="120" />
<timesms mark="81.312" sweep="8.718" compact="0.000" total="90.168" />
<tenured freebytes="1026536000" totalbytes="1073741824" percent="95" >
<soa freebytes="1026536000" totalbytes="1073741824" percent="95" />
<loa freebytes="0" totalbytes="0" percent="0" />
</tenured>
</gc>
<tenured freebytes="1026529000" totalbytes="1073741824" percent="95" >
<soa freebytes="1026529000" totalbytes="1073741824" percent="95" />
<loa freebytes="0" totalbytes="0" percent="0" />
</tenured>
<time totalms="91.359" />
</af>
図 2-58 verbosegc ログ出力例(Global コレクション)
それぞれの出力内容の意味について説明していきます。
ガーベッジ・コレクションの開始はトリガーとなる Allocation Failure の発生を示す<af>タグにより始まりま
す。
<af type="tenured" id="18" timestamp="Sun Jul 23 14:35:43 2006" intervalms="3419.274">
--- 途中省略 --</af>
<af>タグから Allocation Failure についての詳細情報が取得できます。type 属性から Allocation Failure
がどの領域で発生したかがわかります。Global コレクションでは type 属性の値は tenured となります。な
お、Generational Concurrent における Nursery 領域以外で Allocation Failure が発生した場合、つまり
Global コレクションが実施される場合は適用されている GC ポリシーの種類に関わらずすべて tenured と
出力されます(言い換えると世代管理を行わない領域を Tenured 領域と定義できます)。Id 属性はコレク
ション番号、timestamp では Allocation Failure の発生時間、intervalms 属性では前回の Allocation
Failure からの経過時間がそれぞれ記録されます。
<minimum requested_bytes="7000" />
<time exclusiveaccessms="0.074" />
<af>タグの後にはヒープ割り当てに失敗したオブジェクトのサイズ(minimum requested_bytes)と、JVM
の ST コンポーネントがガーベッジ・コレクションを実施するために各種スレッドを停止させるためのロック
を取得して JVM の制御を取得するのに要した時間(time exclusiveaccessms)が出力されます。
<tenured freebytes="1521448" totalbytes="1073741824" percent="0" >
<soa freebytes="447784" totalbytes="1072668160" percent="0" />
<loa freebytes="1073664" totalbytes="1073664" percent="100" />
</tenured>
<tenured>タグには Allocation Failure 時のヒープの空き容量、およびヒープサイズが出力されます。ここ
での出力は soa と loa の領域の和になります。なお、soa は Small object area(通常のオブジェクトを格納
する領域:Large object area 以外の場所)、loa は Large object area のことを示します。
もしこの部分の出力結果から、十分大きな空き領域があるにもかかわらず小さいサイズのオブジェクトの
割り当てに失敗していることが判明した場合は、メモリの分断化(Fragmentation)が発生している可能性
があります。
<gc type="global" id="18" totalid="18" intervalms="3420.464">
<refs_cleared soft="0" weak="0" phantom="6" />
<finalization objectsqueued="120" />
<timesms mark="81.312" sweep="8.718" compact="0.000" total="90.168" />
<tenured freebytes="1026536000" totalbytes="1073741824" percent="95" >
<soa freebytes="1026536000" totalbytes="1073741824" percent="95" />
<loa freebytes="0" totalbytes="0" percent="0" />
</tenured>
</gc>
--- 途中省略 --<time totalms="91.359" />
次に来るのが<gc>タグです。ここから実際のガーベッジ・コレクションによるヒープ開放の結果が出力さ
れています。<refs_cleared>タグにはガーベッジ・コレクションによってクリアーされた参照オブジェクトに
ついての情報が出力されます。<finalization>タグには finalize 処理が実施されるのを待っているオブジ
ェクトの総数が出力されます。<timesms>タグを見ると、Mark、Sweep、Compaction の各フェーズにそれ
ぞれ要した時間を確認することができます。また実際にどれくらいのヒープが開放されたかが<tenured>
タグで挟まれている部分に出力されます。
出力の最後には Allocation Failure が発生してからガーベッジ・コレクションが実施され、各種コントロー
ルが Allocation Failure 発生直後の各スレッドに戻されて処理が再開されるまでに要した時間が出力さ
れます。
Scavengeコレクション
Scavenge コレクションは Generational Concurrent ポリシーを適用した時にのみ発生します。発生のトリガ
ーは Nursery 領域にて Allocation Failure が発生することです。Global コレクション Scavenge コレクショ
ンではオブジェクトの世代管理が行われるため、Global コレクション適用時の verbosegc ログの出力内容
と比較すると Survivor および Tenured 領域へのオブジェクトコピー結果と Nursery および Tenured 領域
毎のヒープ利用状況/開放結果が加わります。
<af type="nursery" id="26" timestamp="Sun Jul 23 14:23:34 2006" intervalms="3377.343">
<minimum requested_bytes="7608" />
<time exclusiveaccessms="0.084" />
<nursery freebytes="0" totalbytes="871995392" percent="0" />
<tenured freebytes="71905008" totalbytes="104857600" percent="68" >
<soa freebytes="66662128" totalbytes="99614720" percent="66" />
<loa freebytes="5242880" totalbytes="5242880" percent="100" />
</tenured>
<gc type="scavenger" id="26" totalid="26" intervalms="3378.584">
<flipped objectcount="7370" bytes="4973564" />
<tenured objectcount="195" bytes="10864" />
<refs_cleared soft="0" weak="0" phantom="10" />
<finalization objectsqueued="145" />
<scavenger tiltratio="89" />
<nursery freebytes="866782600" totalbytes="871995392" percent="99" tenureage="14" />
<tenured freebytes="71773936" totalbytes="104857600" percent="68" >
<soa freebytes="66531056" totalbytes="99614720" percent="66" />
<loa freebytes="5242880" totalbytes="5242880" percent="100" />
</tenured>
<time totalms="7.264" />
</gc>
<nursery freebytes="866774992" totalbytes="871995392" percent="99" />
<tenured freebytes="71773936" totalbytes="104857600" percent="68" >
<soa freebytes="66531056" totalbytes="99614720" percent="66" />
<loa freebytes="5242880" totalbytes="5242880" percent="100" />
</tenured>
<time totalms="7.510" />
</af>
図 2-59 verbosegc ログ出力例(Scavenge コレクション)
Global コレクションの出力と同様に、ガーベッジ・コレクションの開始はトリガーとなる Allocation Failure
の発生を示す<af>タグにより始まります。違いは type 属性が Scagenger コレクションの実施場所を示す
nursery となっている点です。
<af type="nursery" id="26" timestamp="Sun Jul 23 14:23:34 2006" intervalms="3377.343">
<minimum requested_bytes="7608" />
<time exclusiveaccessms="0.084" />
<nursery freebytes="0" totalbytes="871995392" percent="0" />
<tenured freebytes="71905008" totalbytes="104857600" percent="68" >
<soa freebytes="66662128" totalbytes="99614720" percent="66" />
<loa freebytes="5242880" totalbytes="5242880" percent="100" />
</tenured>
--- 途中省略 --</af>
<af>タグに引き続いて出力される内容はヒープ状態を示す情報が Nursery と Tenured 領域に分かれて
表示されている他は Globalコレクションと同じです。出力されている Nursery 領域の大きさは実際には
Allocation 領域の大きさを示しています。そのため、実際に確保されている Nursery 領域に Tiloratio を
掛け合わせた値が表示されます。このときに適用されている Tiloratio はひとつ前のガーベッジ・コレクシ
ョンにて決定されたものです。Scavenge コレクションが実施されるたびに Tiltratio が動的に決定され、そ
の値に基づいて Allocate 領域と Survivor 領域の大きさが定義されます。
<gc type="scavenger" id="26" totalid="26" intervalms="3378.584">
<flipped objectcount="7370" bytes="4973564" />
<tenured objectcount="195" bytes="10864" />
<refs_cleared soft="0" weak="0" phantom="10" />
<finalization objectsqueued="145" />
<scavenger tiltratio="89" />
--- 途中省略 --</gc>
Allocation Failure についての結果に引き続いてガーベッジ・コレクションの実施結果について出力され
ます。Scavenger コレクションでは Allocate 領域から Survivor 領域にコピーされたオブジェクトの数と総サ
イズが<flipped>タグの出力から、Allocate 領域から Tenured 領域にコピーされたオブジェクトについての
情報を<tenured>タグの出力から取得することができます。またこのガーベッジ・コレクションの実施結果
に従って算出された Tiloratio の値が出力されます(scavenger tiltratio="89")。
Concurrentコレクション
最後に Concurrent コレクションの出力について説明します。Concurrent コレクションは Optimize for
Pause Time ポリシーまたは Generational Concurrent ポリシーを適用した場合の tenured 領域にて行われ
ます。
<con event="kickoff" timestamp="Sun Jul 23 14:49:03 2006">
<stats tenurefreebytes="5780072" tracetarget="26818554" kickoff="3647231" tracerate="8.00" />
</con>
<con event="collection" id="16" timestamp="Sun Jul 23 14:49:03 2006" intervalms="7206.956">
<time exclusiveaccessms="0.101" />
<tenured freebytes="2494352" totalbytes="1073741824" percent="0" >
<soa freebytes="359936" totalbytes="1071594496" percent="0" />
<loa freebytes="2134416" totalbytes="2147328" percent="99" />
</tenured>
<stats tracetarget="26818554">
<traced total="14322828" mutators="8502424" helpers="5820404" percent="53" />
<cards cleaned="90" kickoff="1215743" />
</stats>
<con event="completed full sweep" timestamp="Sun Jul 23 14:49:03 2006">
<stats sweepbytes="0" sweeptime="0.031" connectbytes="2359296" connecttime="0.069" />
</con>
<con event="final card cleaning">
<stats cardscleaned="25" traced="7560" durationms="2.230" />
</con>
<gc type="global" id="17" totalid="17" intervalms="3600.506">
<refs_cleared soft="0" weak="0" phantom="4" />
<finalization objectsqueued="149" />
<timesms mark="19.328" sweep="0.492" compact="0.000" total="19.946" />
<tenured freebytes="1006174436" totalbytes="1073741824" percent="93" >
<soa freebytes="1005105936" totalbytes="1072668160" percent="93" />
<loa freebytes="1068500" totalbytes="1073664" percent="99" />
</tenured>
</gc>
<tenured freebytes="1006174436" totalbytes="1073741824" percent="93" >
<soa freebytes="1005105936" totalbytes="1072668160" percent="93" />
<loa freebytes="1068500" totalbytes="1073664" percent="99" />
</tenured>
<time totalms="22.561" />
</con>
図 2-606 verbosegc ログ出力例(Concurrent コレクション)
Concurrent フェーズの始まりは以下の出力で確認できます。
<con event="kickoff" timestamp="Sun Jul 23 14:49:03 2006">
<stats tenurefreebytes="5780072" tracetarget="26818554" kickoff="3647231" tracerate="8.00" />
</con>
この出力は Concurrent フェーズが timestamp 属性で表されている時間に開始(kickoff)したことを示して
います。<stats>タグにはその時の Tenured 領域の空き領域、Concurrent フェーズにおけるアプリケーショ
ン・スレッドのトレース目標、そして Concurrent フェーズ開始のトリガーとなる kickoff 閾値が出力されま
す。
<con event="collection" id="16" timestamp="Sun Jul 23 14:49:03 2006" intervalms="7206.956">
<time exclusiveaccessms="0.101" />
<tenured freebytes="2494352" totalbytes="1073741824" percent="0" >
<soa freebytes="359936" totalbytes="1071594496" percent="0" />
<loa freebytes="2134416" totalbytes="2147328" percent="99" />
</tenured>
<stats tracetarget="26818554">
<traced total="14322828" mutators="8502424" helpers="5820404" percent="53" />
<cards cleaned="90" kickoff="1215743" />
</stats>
--- 途中省略 --</con>
Concurrent トレースが終了し、トレース後に変更された領域の再スキャンも終了すると Concurrent コレク
ション(event=”concurrent”)を開始します。<stats>タグには Concurrent Mark 処理の実施結果が出力され
ます。mutetors 属性の値はアプリケーション(ミューテーターと呼ばれます)がトレースした結果、helpers
属性ではバックエンドで起動されていたスレッドの実施結果をそれぞれ確認できます。また、再スキャン
を行う際にヒープを複数の領域に分割して実施するのですが、その分割された領域をカードと呼ばれ、
Concurrent Mark 中にスキャンされたカード情報が出力されています。
<con event="completed full sweep" timestamp="Sun Jul 23 14:49:03 2006">
<stats sweepbytes="0" sweeptime="0.031" connectbytes="2359296" connecttime="0.069" />
</con>
Concurrent Mark の実施結果の次に出力されているのは Concurrent コレクションフェーズにおける
Sweep 処理の結果です。これに引き続いて以下のカードの再スキャン結果が出力されます。この再スキ
ャンによって Concurrent トレース中にやり残した部分がすべて処理されます。
<con event="final card cleaning">
<stats cardscleaned="25" traced="7560" durationms="2.230" />
</con>
上記で説明した一連の Concurrent フェーズが終了した後に、通常の Global コレクションが実施されま
す。Concurrent フェーズによって部分的にガーベッジ・コレクション処理が事前に行われることで、Global
コレクションに要する時間が短縮されます。
(参考)Concurrent フェーズが終わらないうちに Allocation Failure が発生した場合
Concurrent フェーズによって事前処理が行われている最中に Global コレクションがトリガーされてしまう
ケースもあります。その場合、ST コンポーネントは Concurrent フェーズの途中結果を破棄するか、結果
を Global コレクションの一部に組み入れるかのいずれかの動きをとります。どちらの行動を選択したかは
verbosegc ログの中の<con >タグで”aborted”となっているか”halted”となっているかで判断できます。
Fly UP