はじめに
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リソースとなるが、細かいことを言えば、データベース内部のラッチなども挙げられる。Oracle 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リソースプランで制御可能な項目を以下に示す。- CPUリソースの相対的な使用量としてshares
- CPUリソースの絶対的な使用率(最大値)としてのutilization_limit
- パラレル処理時の絶対的な使用率としての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ネイティブなリソースマネージャーで実現できるかについて、今後の検証で明らかにしていきたいと思う。
コメント
コメントを投稿