5. 設定定義上の絞り込みによる性能チューニング

 

パフォーマンス最大化とシステム安定性の問題
インターネット上で公開されるWebシステムでは、不特定多数の大量ユーザーのアクセスや利用上の様々な振る舞いにより、予め想定されていた処理性能を超えた負荷が発生し、その結果システムの動作や処理の不安定化が引き起こされることがあります。

特に、過負荷によるサーバーアプリケーションの異常停止や処理の同期失敗等は負荷下の一時的な応答性能低下だけでは済まず、様々なビジネス上の損失へとつながる可能性があります。

そのため、サーバーアプリケーションの停止や誤作動を防ぐために、一定量の処理以上の要求に対しては流入量を制限するか、または超過分を処理待ち扱いにし常に一定量以上の負荷が重要な処理部分で発生しないように設定上の上限を設ける手法が一般的に用いられます。

いわゆる流量制御/絞り込みという手法です。

今回は性能問題解決のための絞り込みについて、現実的なアプローチとは何かと考えてみたいと思います。

絞り込みの概要
一般的には絞り込みを行う目的は以下の3つであると言えます。

* 安定化
システムリソース(CPU使用率やメモリ)の限界への到達を防ぎ、提供しているサービス全体やシステム自体が不安定になることを防ぐ。

* バックエンド保護
より重要なバックエンドの処理部分が過負荷になることを防ぐため、フロントエンド側で流量の制御を行って、バックエンドを守る。

* 処理ルートの正常管理
同時に処理しきれないリクエストを、処理待ち行列で待機させたり、予め容易しておいた正規のエラー通知(SORRYページ等)にまわす等、定義済みの管理可能な処理の流れに適合させる。

この絞り込みをおこなうことで、システムが最適化され、応答性能、受け付け処理数、安定性の全てが向上することもあります。

また、設定定義上で絞り込みを実現するために下記の機能がサーバー側で用意されていることが望ましいです。

* 変更可能パラメータ
同時実行処理の数を制限する何らかのチューニングパラメーターが容易されており、設定の変更が可能。

* 計測可能であること
特に絞り込みを通したチューニングや性能管理を行う上では、サーバーの動態を把握するために下記の項目の値が得られることが望ましいです。

o 最大処理可能数
o 実行中のビジー数
o アイドル数
o 待ち行列数
o 単位時間あたりの平均処理時間
o 累積処理件数
o 累積エラー件数

使用するプラットフォームやアプリケーションによっては、予めこれらの機能が用意されており、簡単に取得することが可能なものもありますが、特にアプリケーション部分では、自分達で設計・開発時に意識的に実装し用意しておくという心がけも必要であると思われます。

* 待ち処理の機能
絞り込んだ際に処理に回りきらなかったリクエストを処理待ちとして待機させ、処理余力が回復した時点で順次処理・解消されてゆくようなアプリケーション上の機能(処理待ちキュー、プール、バックログ等)が実装されていること

* エラー処理
処理待ち時のタイムアウトや、待ち行列の上限を超えた場合のリクエストの拒絶等を判り易い形で通知出来るようにしておくことによって、サービス利用側に余計な混乱が生じることを防ぎます。

一般的なWebシステムでの絞り込みポイント
以下の構成のWebシステムの場合、アクセスと処理の流れは下記の通りです。

ユーザーのアクセス
  ↓
ファイアーウォール
  ↓
ロードバランサー
  ↓
Webサーバー
  ↓
APサーバー(J2EE)
  ↓
DBサーバー

その際の主要な絞り込みポイントとして以下が考えられます:

1.ファイアーウォール/ロードバランサー
  ・ネットワーク帯域幅制限
  ・コネクション数(TCP、SSL、HTTPセッション数)制限

2.Webサーバー
  ・TCPソケットLISTEN数(バックログ)制限
  ・同時実行クライアント数の制限

3.J2EE(Webコンテナ)
  ・最大実行スレッド数の制限
  ・スレッド処理待ち数の制限

4.J2EE(JDBCデータソース)
  ・最大プールサイズの制限

システムボトルネック時の絞り込みのチューニング
例えば、CPU使用率やメモリ使用率がそのシステムで限界に達している場合に、これをもってシステムの処理能力の上限である判断し、追加のマシンやハードウェアの購入を検討するというスケールアウトが考えられますが、その前にパラメータをチューニングすることで、同等以上の性能を発揮しながら、システム負荷を下げることも可能です。

特に、各種の同時実行数と待ち行列の上限値を変更が鍵となります。

同時処理数が多すぎてシステムリソースを圧迫している場合には、同時処理数を絞り込むことで、逆に処理の滞り部分の管理のオーバーヘッドを減少させ、結果的にシステム負荷の減少や、スループットの向上が得られる場合等が考えられます。

基本的な絞り込みのアプローチ
もちろん、それぞれの具体的なパラメータ名や、デフォルト値、推奨値、設定方法等についてはシステム構成やアプリケーションの種類によって異なります。

もし、全ての区間の入り口と出口で、処理量が常に一定の比例関係を維持出来ている場合には、絞り込み設定は、最も先頭の入り口の部分での制限(このケースでは、ファイアーウォールのネットワーク帯域幅制限)を行うだけで十分制御が可能であると言えます。

しかし、実際には、ユーザーの振る舞いやリクエストの種類によって、例えば、1アクセスあたりのスレッド数やクエリ発行数は異なってしまうために、入り口と出口の比率で変動が生じる部分には、それぞれ制限数を設けて管理する必要があります。

* 設計段階
手順としては、まずシステム構成の設計段階において、アプリケーションやシステムの動作を推測して、おおまかなパラメータ毎の予測値を算出し、それぞれ上限設定を定義しておきます。

* 負荷テスト
そして、システムの総合テスト段階で、負荷テストを行います。
この負荷テストは、実際のユーザーの利用ケースに即したアクセスを生成し、実際のシステムの振る舞いに近い状態を再現する必要があります。もし、利用ケースが異なれば先述の入り口と出口の比率の関係が変わりますので、最適な絞り込みの設定パラメータも異なってしまいます。
この負荷テストで、予め要求されている性能目標(応答速度やボリュームや機能性)が 維持出来ているならば、特に絞り込みを行う必要性は無いでしょう。

* 性能目標を達成できなかった場合
もし、性能目標を満たすことが出来なかった場合には、ボトルネックを解析し、その要因を突き止め、改善方法を追求する必要があります。ボトルネックは基本的にはサーバー構成単位で負荷の切り分け、コンテナ単位での処理待ち発生の切り分けによって解析する方法を用います。
切り分けに際しては、e-Test suiteのServerStats等の負荷の量やユーザー操作毎の応答速度と、サーバー側のシステム負荷やパフォーマンスメトリックのグラフによる相関分析が出来るツールが便利です。

* 切り分け時に着目するポイント
特に以下のパラメータに着目して、関連情報を分析することで切り分けが容易になります。

1.各サーバーのCPUやメモリ使用率
2.プロセス毎のCPUやメモリ使用率
3.グラフ上でピークに達して頭打ち減少を起こしているパラメータ
4.ページの応答速度の劣化のタイミングで急激に変化しているパラメータ
5.入り口と出口の流量の比例関係が変化しているポイント
6.処理待ち数の大量発生

* ボトルネック解明後
遅延要因を突き止めた場合には、その内容を改善出来そうな絞り込みの設定の変更(チューニング)を行います。ここでは、もし確実な最適値が算出出来ていなくても構いません。
修正した推測値を設定し、再度、負荷テストを行って実際に性能を検証することが改善状況の確認の上で重要ですので、絞り込みのパラメーターを最適値に導くまでに何度かの繰り返しの負荷テストを行うというプロセスが必要となります。