スキップしてメイン コンテンツに移動

12cでリソースの共有と非共有のはざまで... その1

はじめに

 2013年のJPOUG Advent Calendarも今日で最後になりました。私のAdvent Calendarネタに関しては、若干、旬を過ぎた感は否めませんが、Oracle Database 12cに関するものにしようと思います。

 実は、Oracle Database 12cリリース時に某メディアに寄稿予定だったものを(いろいろ事情があってお蔵入りになっていたもの)この場を借りて、全3回でお送りしようと思います。

Oracle Database 12c マルチテナント・アーキテクチャについて

 Oracle Database 12cの"c"がCloudを意味するようになり、プライベートやパブリックを問わずデータベースを集約して効率良くデータベースの集積率を高めるようなアーキテクチャを備えた今、"c"であるためのポイントは、集約した結果として物理的なリソースをどのように適切に配分するのか?また、物理的なリソースを適切に配分できるのか?ということに尽きると思う。

 物理的なリソースとはデータベースが使用するCPUリソース、Memoryリソース、I/Oリソースとなるが、細かいことを言えば、データベース内部のラッチなども挙げられる。

 O
racle Database 12cでは、どのようなリソース管理が可能かについて検証していくつもりです。また、Oracle Database 12cのマルチテナント・アーキテクチャで、データベースにおける各種リソースの管理方法が旧来のリリースから変更されており、合わせてOracle Database 12cがどのようにリソースを管理しているかについても適宜、検証を行いたい。

 まず、簡単にマルチテナント・アーキテクチャをおさらいしておく。




 マルチテナント・アーキテクチャを簡単に理解すると、OSの持つリソースはコンテナ・データベースが管理し、プラガブル・データベースは、あたかも従来のスキーマのような振舞い(しかし、個別のデータベースとして隔離されて動作する)をしているように見える。

 プラガブル・データベースの追加は、スキーマ追加と同様にCPUやメモリーといった新たなリソースを確保する必要はない。必要な時に、必要なだけ、上位のデータベース(コンテナ・データベース)が用意する。

注意
誤解があるといけないが、マルチテナント・アーキテクチャとスキーマ・アーキテクチャとは全く異なるものであるが、ここでは、私の受ける印象として"似ている"という趣旨を記載しています。

 これにより、1つのコンテナ・データベースに多くのプラガブル・データベースが格納可能であり、従来のデータベースに対するメンテナンス(バックアップやパッチ適用など)の多くは1つのコンテナ・データベースに対して1回行えば良くなる。

 しかしながら、多くのプラガブル・データベースが混在する場合、OSおよびデータベース内の様々のリソースの使用方法を細かく制御する事が重要なキーワードとなる。




CPUリソース編

 データベース側でリソース制御を行うには、Resource Limit(Profile)やDatabase Resource Manager(Enterprise Editionが必須)がある。また、Database Resource Managerと初期化パラメーターCPU_COUNTを利用したインスタンス・ケージングがあるが、Oracle Database 12cのDatabase Resource Managerでは、プラガブル・データベース単位やサービス単位など、さらに細かい粒度でリソース制御が可能になっている。

 筆者の環境は複数のコンテナ・データベースがあり、さらにコンテナ・データベース内には複数のプラガブル・データベースが存在している。そのような環境では、コンテナ・データベース間でインスタンス・ケージングを利用し、さらにリソース制御下の各コンテナ・データベースで各プラガブル・データベースのCPUリソースを制御したいわけだが、インスタンス・ケージングとCDBリソースプランを同時に利用することで、柔軟なCPUリソース管理が可能になる。

 また、目新しいところでいけば、Linuxプラットフォームにおける初期化パラメーターPROCESSOR_GROUP_NAMEがある。これは、OSがもつネイティブなリソースマネージャ(LinuxでいうところのControl Groups(以下、cgroups))の設定をインスタンス全体に適用するものである。パラメーターがPROCESSOR_GROUP_NAMEということでCPUリソースのみを管理しているようだが、実際、OSのもつリソース管理機構全体を利用できる。これは、今後のI/Oリソースの制御の部分で詳しく述べたい。

 以下、Database Resource Managerのマルチテナント・アーキテクチャへの拡張部分と、初期化パラメーターPROCESSOR_GROUP_NAMEを使ったCPUリソースの制御方法と結果を見ていきたい。

Database Resource Managerを使用した場合

 コンテナ・データベース上で、各プラガブル・データベースのCPUリソースを制御するDatabase Resource ManagerとしてCDBリソースプランが追加された。CDBリソースプランで制御可能な項目を以下に示す。


  1. CPUリソースの相対的な使用量としてshares
  2. CPUリソースの絶対的な使用率(最大値)としてのutilization_limit
  3. パラレル処理時の絶対的な使用率としてのparallel_server_limit

 このCDBリソースプランを使って、コンテナ・データベース内の各プラガブル・データベースのCPUリソースを制御できる。

 以下は、コンテナ・データベース名IQCDB02における各プラガブル・データベースのCPUリソースを制御するサンプルとなる。

exec DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();

BEGIN
  DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN(
    plan    => 'IQCDB02',
    comment => 'CDB resource plan for IQCDB02');
END;
/

BEGIN
  DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(
    plan                  => 'IQCDB02', 
    pluggable_database    => 'PDB02', 
    shares                => 7,
    utilization_limit     => 87.5,
    parallel_server_limit => 87.5);
END;
/

BEGIN
  DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(
    plan                  => 'IQCDB02', 
    pluggable_database    => 'PDB03', 
    shares                => 1,
    utilization_limit     => 12.5,
    parallel_server_limit => 12.5);
END;
/

exec DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
exec DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();

ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'IQCDB02';

 また、検証で使用したCPUに負荷をかけるサンプルコードを以下に示す。

 今回の検証用マシンは2CPU(16コア)のマシンを使っているが、いくつかのパターンで検証を行う。また、データベースにCPU負荷をかけるコードは以下を使っている。

declare
 t number;
begin
 for i in 1 .. 50000000 loop
  for j in 1 .. 100 loop
   t := t + 1;
  end loop;
 end loop;
end;
/

このPL/SQLコードを16セッションで同時実行する


パターン1

 CDBリソースプランを使用せずに、同一コンテナ・データベース内の複数のプラガブル・データベースに負荷をかける








 OSとしても、データベースとしてもリソース制限をかけていない状態だと、2つのプラガブル・データベースのワークロードはOSのプロセススケジューラーにより自動でスケジュールされ、ほぼプラガブル・データベース毎にほぼ同じだけのリソースを使うので、全体のCPU使用率は100%となり、処理時間も同じような結果となる。

パターン2


 CDBリソースプランを使用して、以下の相対的なCPU使用量を設定して負荷をかける



 これは、CPUリソースが枯渇した場合、CDBリソースプラン中のsharesで指定された総数(7+1=8)の内、各プラガブル・データベースにCDBリソースプランで指定した分だけ、CPUリソースを割り振る。この場合、PDB2には、CPUを7/8=87.5%割り振ることを意味している。



 パターン1で、均等のCPUリソースを割り振られたとするとPDB2には50%のCPUリソースが割り振られたことになる。パターン2では、87.5%が割り振られることになるので、処理は約1.75倍パフォーマンスアップしている計算になる。実際、パターン1で2分7秒だった処理が、1分20秒となり、パフォーマンスアップは約1.59倍。パターン1でのCPUリソースの割り振りが厳密に均等でないことを考えると、リソース管理としては十分合格点だと言える。

 さらに、パターン2のPDB3では、1/8しかCPUリソースが割り振られないにも関わらず、パターン1とほぼ同じパフォーマンスとなっている。これは、sharesパラメーターがCPUリソース枯渇時のみ有効であるため、PDB2の処理が終了し、CPUリソースに空きができたため、PDB3はその空きリソースを使用して処理している。これは、パターン2実施時のCPU使用率のチャートを見てもPDB2およびPDB3の処理が終了するまで、CPU資料率が100%であったことからも分かる。

パターン3


 CDBリソースプランを使用して、以下の絶対的なCPU使用量を設定して負荷をかける



 これは、パターン2のテストに加えて、CPU使用率の上限を絶対値で指定している。つまり、utilization_limitを指定すると、CPUリソースに空きがあっても、指定された上限を超えないようリソース制限がかけられる。




 PDB2はパターン2の時と大きく処理時間の変化はないが、PDB3では、処理時間に大きな変化があることがわかる。これは、CPU使用率のチャートからわかるように、全体のCPUリソースに空きがあっても、utilization_limit(PDB3の場合は12.5%)を超えないように調整された結果だと分かる。

パターン4


 インスタンス・ケージングとCDBリソースプランを使用して、複数コンテナ・データベースでCPU使用量を定義しつつ、プラガブル・データベースごとにもCPU使用量を設定して負荷をかける



 これは、パターン2のテストに加えて、コンテナ・データベースに対してインスタンス・ケージングを行っている。つまり上記のIQCDB02というコンテナ・データベースは全16CPUコア中、8CPUコアの制限がかけられている。その制限の中で、sharesパラメータによりさらにプラガブル・データベースにCPUリソース制限がかけられる事になる。




 パターン4では、使用可能なCPUリソースをパターン2のテストを比較して半分としたことから、処理時間も概ね倍の時間となった。また、CPU使用率のチャートからも、CPU使用率が50%を超えないようにリソース制御されていることが分かる。

OS ネイティブなリソースマネージャーを使った場合


 初期化パラメーターPROCESSOR_GROUP_NAMEを使用することで、Database Resource ManagerなしにOSのネイティブな機能を利用して、インスタンス・ケージングを行うことが可能になる。

注意
Linuxにおけるcgroupsの説明は紙面の都合上割愛するが、データベース側の$ORACLE_HOME/rdbms/install/setup_processor_group.shが参考になるので、興味のある方は覗いてみると良いと思う。ちなみにこのスクリプトはLinuxとSolarisのOSネイティブなリソースマネージャーに対応しているようである。


 検証環境のcgroupsの設定は以下の通り。




 OSネイティブなリソースマネージャー(cgroups)によりコンテナ・データベース全体がCPUリソース50%を超えないように調整されている。そのため、Database Resource Managerを使用したパターン1の場合と比較して、約2倍の処理時間となっていることが分かる。

 ただし、cgroupsがプロセス(スレッド)単位でOSがリソース制限をすることと、マルチテナント・アーキテクチャにおいて、プラガブル・データベース毎に、プロセスを生成するわけではないことを考えると、プラガブル・データベース毎にPROCESSOR_GROUP_NAMEでCPUリソースを制御することは不可能と言える。当然ながら、プラガブル・データベースでは、PROCESSOR_GROUP_NAMEパラメーターは変更できない。

OS ネイティブなリソースマネージャとCDBリソースプランを併用した場合


 今回、OSネイティブなリソースマネージャーとDatabase Resource Managerを併用した際、どのような動作になるのかも検証した。実際の運用において、どちらか一つに管理をまとめる方が運用効率が良いので、この併用プランを選択する必要性はないが、PROCESSOR_GROUP_NAMEをCPUリソースだけで使用しない場合(今後のI/Oで検証予定)を想定して、一応動作確認しておく。

検証環境のcgroupsの設定は以下の通り。






 OSネイティブなリソースマネージャー(cgroups)によりコンテナ・データベース全体がCPUリソース50%を超えないように調整されている。さらにCDBリソースプランにより各プラガブル・データベース間でのリソース管理が行われ、Database Resource Managerを使用したパターン4の場合と比較して、概ね同じ処理時間となっていることが分かる。

 本検証より、PROCESSOR_GROUP_NAMEとCDBリソースプランは併用しても期待通り動作していることが分かった。

CPUリソースを制御するといった観点でのまとめ


 本検証により、マルチテナント・アーキテクチャにおいて、CPUリソースの制御はDatabase Resource ManagerのCDBリソースプランによりかなり細かく制御が可能だと分かった。反面、Database Resource Managerでは、基本的にCPUリソースの制御しか提供されておらず、MemoryリソースやI/Oリソースの制御に関して疑問が残るのも事実である。

 今回、OSネイティブなリソースマネージャーを使用したのは、Database Resource Managerでの不足分を補うことが可能か否かを検証するためであるが、CPUリソース以外(特にI/Oリソース)の制御をOSネイティブなリソースマネージャーで実現できるかについて、今後の検証で明らかにしていきたいと思う。

コメント