パート2:チューニング
適切なパラメータを見出す
ミドルウエアのパラメータをチューニングすることも,サーバーのサイジングと性能改善には必要である*7。重要なものは,Web,AP,DBそれぞれのプロセス/スレッド数,DBサーバーへのコネクション・プール数と,以上のバランスである。これに加えて,JavaであればJavaVMのヒープ領域のサイズも性能に影響を及ぼす。
まず,プロセス/スレッド数とコネクション・プール数を調整する前提として,これらの値は固定値で運用するべきである。リソースを動的に確保したり開放する際のオーバーヘッドを無くすためである。稼働させるプロセスとスレッドに応じたメモリー容量とCPU処理能力も搭載していなければならない。
WebサーバーではクライアントからのHTTPリクエストを受ける数を固定する。標準では最小プロセス数と最大プロセス数が異なっており,アクセス状況に応じて動的にプロセス数が変わるようになっている。WebシステムにおいてWebサーバーはHTTPリクエストの処理にしか使わないので,アイドル状態のプロセスがメモリーを消費していても問題はない。
プロセス/スレッド数とコネクション・プール数は,密接な関係にある(図7[拡大表示)。クライアントからのリクエストとDBアクセスをつなぐ経路の込み具合を,パラメータで決められる。一般にはフロントエンドからバックエンドにかけて,経路となるパラメータの値を減らしていく実例が多い。
GCの頻度と時間を最小化
JavaVMのヒープ領域のサイズも性能に影響を及ぼす。ヒープ領域のチューニング次第で,ガベージ・コレクション(GC)*8の発生頻度と処理時間を調整できる。Webシステムによっては,GCの発生時に分単位でサーバーが停止することもあり得る。
JavaVMは,生存期間の違うオブジェクトを別々に管理することで,GCのオーバーヘッドを軽減する(図8[拡大表示)。図8中のEdenと呼ばれる領域は,作られたばかりの新しいオブジェクトを置く場所である。ほとんどのオブジェクトは一時的に作られ,GCによってすぐに寿命を迎える。一方で,よく使われるオブジェクトであるがために,GCを経ても削除されずに生き残るものもある。生き残ったオブジェクトは図中のSurvivorと呼ぶ領域にコピーする。さらにその後のGCでも生き残ったオブジェクトは,図中のOldと呼ぶ領域にコピーする。
Old領域と,EdenとSurvivorからなるYoung領域との一番の違いは,それぞれのGCで用いるアルゴリズムである。Young領域を対象とするスカベンジGCでは「Copying」と呼ぶアルゴリズムを用いる。生き残ったオブジェクトを世代ごとに分かれたメモリー領域にコピーするものだ。メモリー・アドレス空間を無駄に消費するためメモリー効率が悪くなるが,1回のGCにかかる時間が短い。これに対して,Old領域を対象とするフルGCでは「Mark-compact」と呼ぶアルゴリズムを用いる。1回のGCでシステムが停止する時間がCopyingよりも長い。
チューニングでは,JavaVMの起動時オプションによって,ヒープ領域全体のサイズのほか,GCで用いる個々のメモリー領域のサイズを決められる。「Old領域を対象としたフルGCをいかに発生させないか,または,発生した際のシステム停止時間をいかに短くするかがポイント」(ウルシステムズの埋金進一シニアコンサルタント)となる*9。
GCの効率を上げるためには,アプリケーションの開発時にも,オブジェクトのサイズを小さく収める工夫が必要になる。例えばJSPのソースが大きくなる場合には,ソースコードを分割するといった工夫が望ましい。