津島博士のパフォーマンス講座 Indexページ ▶▶

 


皆さんこんにちは、だいぶ寒くなってきましたが体調はいかだでしょうか。私は軽い風邪をひいてしまいました。皆さんも気を付けて下さい。

今回は、少し特殊な内容になりますが、共有サーバー構成について説明しようと思います。これについては、搭載するメモリ容量の増加により、あまり利用されなくなってきたと思っていたのですが、まだ使用しているシステムも多いようですので、参考にして下さい。

■ 1. 共有サーバー構成とは
まずは、共有サーバー(以前はMTS:マルチ・スレッド・サーバーと呼んでいました)構成とは何かを説明しましょう。
一般的な構成では、コネクションしている間、サーバー・プロセスが起動されているため、セッションが多くなるとプロセス数が多くなってリソースを多く使用してしまいます(これを専用サーバーといいます)。これを改善するものが共有サーバー構成です。共有サーバー構成は、サーバー・プロセスを複数のセッションで共有してSQL単位で切り替えて使用することで、使用するリソース(メモリなど)を少なくすることが可能な構成です。以下の図のようにディスパッチャ・プロセス(ディスパッチャ)、共有サーバー・プロセス(共有サーバー)、要求キュー、応答キューで構成され、サーバー・プロセスをアイドル状態がないように効果的に利用します。ただし、ディスパッチャ経由になっているため専用サーバーより多少のオーバーヘッドはあります。 Oracle Database 11g(Oracle11g)からのデータベース常駐接続プーリング(DRCP)を使用すると専用サーバーでもリソースを効果的に使用できるようになります(SQL単位ではなくセッション単位に専用サーバーを共有することができるのでプロセス数を少なくできます)。これについては別の機会で説明したいと思います。


共有サーバー構成は、以下の①~⑤のようにバーチャル・サーキットを使用してアクセスされます。
① ユーザ・プロセスから接続されるとディスパッチャがバーチャル・サーキットを作成します
② ディスパッチャが対応のバーチャル・サーキットを共有の要求キューに入れます
③ 共有サーバーが要求キューからバーチャル・サーキットを取得してデータベースにアクセスします
④ 実行結果を対応の応答キュー(ディスパッチャごとに専用)に入れてバーチャル・サーキットを解放します
⑤ ディスパッチャが応答キューから結果をユーザに返します
共有サーバー構成は、初期化パラメータSHARED_SERVERSを0以外にすることで使用できるようになります。このときTCP/IPプロトコルに対して1つのディスパッチャがデフォルトで起動されます。
OLTPシステムのような(短時間のSQL処理を数多く行うような)場合は共有サーバー構成は効果的ですが、バッチ処理やDWHなどは共有サーバーをあまり切り替えることができないので効果的ではありません。このような処理を同時に行うような場合は、共有サーバーと専用サーバーを同時に使用することも可能です(それぞれを共有サーバー接続と専用サーバー接続といいます)。このときに、専用サーバー接続を使用する場合はネット・サービス名の接続記述子にSERVER=DEDICATED句を含めます。それでは、それぞれについてもう少し詳細に説明します。

(1)共有サーバー
共有サーバーは、初期化パラメータSHARED_SERVERSで指定したプロセス数が起動されます。PMONプロセスが負荷に応じて、使用可能な共有サーバーの最大数(初期化パラメータMAX_SHARED_SERVERS)まで自動的に起動または停止を行います(最大数のデフォルト値はないので指定して下さい)。SHARED_SERVERSは、共有サーバーの最小数です(常に起動されているプロセス数です)ので、リソースを無駄に使用しないように注意が必要です。 初期化パラメータSHARED_SERVER_SESSIONSには、共有サーバー接続を行うセッションの最大数を指定できます。これに初期化パラメータSESSIONSより少ない値を指定すると、専用サーバー接続するためのセッション数を予約することができます。共有サーバー接続は、1つのSQL処理が長いような場合にはあまり効果がないため、このような処理を行う必要がある場合には、SHARED_SERVER_SESSIONSとMAX_SHARED_SERVERSを設定して専用サーバー接続するためのセッションとプロセスを確保するのが有効です。

(2)ディスパッチャ
ディスパッチャは、初期化パラメータDISPATCHERSと初期化パラメータMAX_DISPATCHERSで指定しますが、ディスパッチャの数は共有サーバーのように動的にPMONによって起動または停止されるものではありません(つまり、現在は初期化パラメータMAX_DISPATCHERSは使用していません)。ディスパッチャ数は、データベース管理者の判断のもとに初期パラメータDISPATCHERSのDISPATCHERS属性を変える必要があります(次のコマンドでOracleデータベース起動中に動的に変更することができます)。そのため、設定するには多少の注意(多過ぎてリソースを無駄に使用しないように、少な過ぎてパフォーマンス問題にならないように)が必要です。

SQL> ALTER SYSTEM SET DISPATCHERS=”(PROTOCOL=<プロトコル>)(DISPATCHERS=<ディスパッチャ数>)”;

システム負荷が増加してディスパッチャのスループットが限界になった場合に、ディスパッチャを追加することが適切とはかぎりません。そのかわりに、ディスパッチャの接続プーリング(接続プーリング)やOracle Connection Managerのセッション多重化(セッション多重化)によって、より多くのクライアント(セッション数)をサポートできるようにディスパッチャの構成を検討して下さい。これは、1つのディスパッチャに対する接続数(コネクション数)には限界があるため、ほとんどの時間アイドル状態である場合は、1つのディスパッチャでサポートするセッション数を増加する方が効果的だからです(最近のJavaアプリケーションは、アプリケーション・サーバーの接続プーリングを使用する場合が多いので、使用する必要はないと思います)。

・接続プーリング
接続プーリングは、アイドル時間のタイムアウト(デフォルトは10秒)を使用してディスパッチャがセッションの切り替えを行います(タイムアウトが発生すると切り替えます)。接続プーリングを使用する場合には、以下のように初期化パラメータDISPATCHERSのPOOL属性を指定します(以下の例は、接続できるコネクション数が50までに対してセッションを500まで行えるように設定しています)。

SQL> ALTER SYSTEM SET DISPATCHERS=”(PROTOCOL=tcp)(DISPATCHERS=1)(POOL=on)
(connections=50)(sessions=500)”;

セッション多重化
多重化は、Connection Managerプロセス(Oracle Connection Managerを使用した場合)で、複数クライアントから個別のディスパッチャへ接続する場合に使用します(例えば、10個のクライアントがConnection Managerプロセスからの1つの接続を経由して1つのディスパッチャに接続できます)。ディスパッチャでセッション多重化を使用する場合には、以下のように初期化パラメータDISPATCHERSのMULTIPLEX属性を指定します。

SQL> ALTER SYSTEM SET DISPATCHERS=”(PROTOCOL=tcp)(DISPATCHERS=1)(MULTIPLEX=on)”;

(3)バーチャル・サーキット
共有サーバー構成の場合、ユーザーからの処理要求はディスパッチャを通して、共有サーバーに伝えられ、共有サーバーが処理を行い、ディスパッチャに応答を返します。この際に共有プール上に存在するバーチャル・サーキットを通じて、ディスパッチャと共有サーバーの処理要求のやり取りが行われます。バーチャル・サーキットは、基本的にデータベースへの接続時に作成され、切断時に解放されます。初期化パラメータCIRCUITSでバーチャル・サーキット数の最大数を指定します。この初期化パラメータのデフォルト値はありません(初期化パラメータDISPATCERSのSESSIONS属性やCONNECTIONS属性の値または共有プール・サイズにより決まります)。つまり、共有サーバー接続するセッション数を制限したい場合に指定しますので、あまり気にする必要はありません。

 

(4)ラージ・プールと共有プール
共有サーバー接続を使用するとUGA(ユーザー・グローバル領域)はラージ・プールに作成されます。このとき、第7回で説明したようにラージ・プールが使用できない場合は共有プールが使用されますが、共有プールは様々な用途に使用されていますので、ラージ・プールを使用するようにして下さい。ラージ・プールは、初期化パラメータLARGE_POOL_SIZEを指定すると使用されますが、自動メモリ管理(自動SGA管理も同様です)を使用していると自動的に算出されます。つまり、自動メモリ管理が有効になっている場合はラージ・プールが使用されますが、無効になっている場合には初期化パラメータLARGE_POOL_SIZEの値で決まります(0の場合は共有プール、0以外の場合はラージ・プールが使用されます)。そのため、自動メモリ管理を使用すれば気にする必要はありません。

 

(5)自動PGAメモリ管理について
UGAは、セッションが接続している間、使用されるセッション情報(ソート領域など)です。このUGAは、共有サーバー接続の場合には共有メモリ(SGA)に確保されるので、自動PGAメモリ管理を使用することができません。そのため、メモリ・チューニングするのが難しくなります。
第14回でOracle Database 10g(Oracle10g)から自動PGAメモリ管理を使用できるようになりましたと説明しましたが、ここでもう少し詳しく説明しようと思います。Oracle10gからは、自動PGAメモリ管理を使用するとUGAはPGAに確保されます。そのため、ソートなどの領域を使用中の場合は、他のセッションで共有サーバーを再利用することができなくなります(自動的に専用サーバー接続のように行うことになります)。そのような共有サーバーが多くなると、共有サーバーが不足してくることになり、共有サーバー構成のメリットが失われてきます(共有サーバー数の調整も難しくなります)。大量のUGAを使用するようなプログラムでは,共有サーバー接続を使用するのではなく専用サーバー接続にするようにして下さい。だから、バッチ処理やDWHなどの処理では共有サーバー接続より専用サーバー接続の方が効果的なのです。

共有サーバー接続のUGAについて
ご存知ない方のために、ここで共有サーバー接続のUGAについて簡単に説明します。 共有サーバー接続では、サーバー・プロセスを多くのセッションで共有して使用するため、処理途中のデータ(UGA)をプロセスのローカル・メモリ(PGA)に持っておくことができません。例えば、検索処理(SELECT文)を実行すると内部的にはPARSE(実行計画の作成), EXECUTE(実行), FETCH(データを1行取得)を行います(FETCHはデータ行数分行われます)が、それぞれは同一の共有サーバーで行われるとは限りません。このとき、ソートなどはEXECUTEで行われるためFETCHがすべて終了するまでPGAに持っておくことができないからです。 そのため、Oracle9iR2まで(Oracle10gからは手動PGAメモリ管理の場合)は、UGAは共有メモリ(SGA)を使用しますが、以下の図のようにソート処理の場合は、初期化パラメータSORT_AREA_RETAINED_SIZEまでソート領域としてSGAを使用します。それ以上ソート領域が必要になると初期化パラメータSORT_AREA_SIZEまでは、共有サーバーのPGAが使用されます(これは、ソートに大きな領域を使用する場合でも、あまりSGA上に確保しないようにするためです)。この共有サーバーのPGAに取られたソート領域は、ソート処理が終了した時点(EXECUTE)で解放されるため、FETCHが終了するまでアクセスできるよう一時セグメントに保管します。つまり、SORT_AREA_SIZE以下であっても一時セグメントを使用する場合があるため、設定するのが大変になります。

 

■ 2. 共有サーバー構成のチューニング

ここからは、共有サーバー構成のチューニングについて説明します。 共有サーバー接続を使用してもチューニング方法は基本的には変わりません。また、最新のOracle11gになっても基本的な考え方は変わっていませんので、以前からと同様にパフォーマンスに大きく影響するディスパッチャ数と共有サーバー数のチューニングが必要になります。これは多くても少なくても問題になりますので、効率の良い数を起動する必要があります。つまり、この二つのプロセス数と共有サーバー接続固有のメモリ・チューニングが必要になります。メモリ・チューニングは自動メモリ管理を使用すると気にする必要はないので、ここでは二つのプロセスについて説明します。 共有サーバー構成のベストなプロセス数は、システムごとに(アイドル時間が多いなどによって)異なってきますので、推奨値などはありません。システムごとに十分なテストを行って、ベストなプロセス数を設定する必要があることは忘れないで下さい。また、共有サーバー構成を使用するシステムは、メモリが少ない環境でセッションを多く使用できるようにリソースの使用を最小限にすることが目的ですので、パフォーマンスを向上するためにプロセス数を増加するのは簡単ではありません(メモリ不足になる可能性があります)。メモリが不足すると様々な問題が発生し易くなりますので、そのような場合はメモリを追加する(または同時接続数を少なくする)なども大事であることは忘れないようにして下さい。

(1)ディスパッチャの数
ディスパッチャの数は、同時接続50程度に対して1つのディスパッチャが目安といわれていますが、システムごとにベストな数は異なってきますので、テストする開始点レベルと思って下さい。ディスパッチャの数が多過ぎて無駄なリソースを使用していないか、少な過ぎてパフォーマンスの問題がないかを動的パフォーマンス・ビューV$DISPATCHER、V$QUEUE、V$DISPATCHER_RATEで確認します。 V$DISPATCHERビューとV$QUEUEビューを使用して次のSQLのように実行して”%BUSY”(ディスパッチャのビジー率)と”AVG WAIT TIME(msec)”(リクエスト・キューの平均待機時間)を確認します。%BUSYが50を超えている場合や”AVG WAIT TIME(msec)”が一貫して増加している(ディスパッチャの競合を示す)場合は、ディスパッチャ数を増やすことを検討します。STATUS=”WAIT”はアイドル状態ですので、%BUSYが少なくアイドル状態が一貫して存在する場合は少なくすることを検討します。

V$DISPATCHER_RATEビューのそれぞれのCUR_列(現在の値)、AVG_列(平均値)、MAX_列(最大値)を以下のように参照して多いか少ないかを確認します。

  • CUR_とAVG_がMAX_を大きく下回る場合は、ディスパッチャ数の削減を検討します
  • CUR_とAVG_がMAX_に近い場合は、ディスパッチャの追加を検討します
    システム使用率(負荷)が低い期間と高い期間の両方で、最初の統計と後の統計をそれぞれ調べて、
    共有サーバーの負荷パターンを識別した後で、それに従ってパラメータを調整して下さい。

(2)共有サーバーの数
共有サーバーの数は、同時接続10程度に対して1つの共有サーバーが目安といわれていますが、これもテストする開始点レベルと思って下さい。共有サーバーは、PMONによって自動的にプロセス数が調整されるので、共有サーバーの最小数が多過ぎて無駄なリソースを使用していないか、最大数が少な過ぎて待機が多くないかを動的パフォーマンス・ビューV$SHARED_SERVER_MONITOR、V$SHARED_SERVERで確認します。 V$SHARED_SERVER_MONITORビューを次のSQLのように実行してSERVERS_STARTED(インスタンス起動後に起動されたサーバー数)、SERVERS_TERMINATED(インスタンス起動後に停止したサーバー数)、SERVERS_HIGHWATER(インスタンス起動後に同時実行した共有サーバーの最大数)を確認します。SERVERS_HIGHWATERがMAX_SHARED_SERVERSに達している場合はMAX_SHARED_SERVERSを大きくすることを検討して下さい(SERVERS_STARTEDとSERVERS_TERMINATEDがすぐに多くなるような場合は、SHARED_SERVERSが少ないことですので増加することを検討して下さい)。MAXIMUM_CONNECTIONS(インスタンス起動後のバーチャル・サーキットの最大数)、MAXIMUM_SESSIONS(インスタンス起動後の共有サーバー・セッションの最大数)も初期化パラメータCIRCUITS、SHARED_SERVER_SESSIONSを確認して、達している場合は大きくすることを検討して下さい。

SQL> SELECT * FROM v$shared_server_monitor;

MAXIMUM_CONNECTIONS MAXIMUM_SESSIONS SERVERS_STARTED SERVERS_TERMINATED SERVERS_HIGHWATER
------------------- ---------------- --------------- ------------------ -----------------
                  0                0               0                  0                 1

上記のSERVERS_STARTEDが0になっている場合は、1度も追加起動していないことなのでSHARED_SERVERSが多過ぎる可能性があります。そのため、V$SHARED_SERVERビューを次のSQLのように実行して、%BUSY(共有サーバーのビジー率)とSTATUSがアイドル状態”WAIT(COMMON)”かを確認します。これについても%BUSYが少なくアイドル状態が一貫して存在している場合は初期化パラメータSHARED_SERVERSを少なくすることを検討して下さい。

■ 3. おわりに

今回は共有サーバー構成について説明しました。また機会があれば他のことについても説明したいと思います。11/20(火)にOracle DBA & Developer Days 2012で久しぶりに講演をしました。昨年に続いて2回目の博士としての講演になりますが、聞いてくれた方はありがとうございました。これからも頑張りますのでよろしくお願いします。質問をお待ちしています。 それでは、次回まで、ごきげんよう。


ページトップへ戻る▲ 

 

津島博士のパフォーマンス講座 Indexページ ▶▶