Oracle RACの仕組みを理解しよう ~データベース接続および負荷分散の仕組みについて~

イントロ

今回はOracle RACのデータベース接続および負荷分散の仕組みを説明しております。Oracle RACの概要については別途説明していますので、Oracle RACとは何か理解が浅い方はまず下記をご参照ください。
Oracle RACの仕組みを理解しよう ~ClusterwareおよびASMで実現する機能について~

ローカルリスナーを使用したデータベース接続

Oracle RACにおける接続を説明する前に、まずはOracle RACを導入していない構成におけるデータベース接続の仕組みを見ておきましょう。ローカルリスナーというプロセスがクライアントとデータベース間の接続を仲介する動きをします。データベース接続の流れを下図に記載します。

  1. クライアントのユーザプロセスからデータベースサーバのローカルリスナーに対して接続要求を行う
  2. ローカルリスナーがサーバプロセスの起動を行う
  3. ユーザプロセスとサーバプロセス間で接続が確立される

SCANリスナーを使用したデータベース接続

続いてOracle RAC構成におけるSCANリスナーを用いたデータベース接続について説明します。SCANとはSingle Client Access Nameの略で、クライアントからデータベースに接続する際に単一の名前を指定して接続できる、つまりDNSに登録するのはひとつの名前だけでよいという点が特徴となります。単一の名前を用いることで、Oracle RAC構成にノードを追加・削除したとしてもクライアント側の接続設定を変更する必要がないという点がメリットになります。下記にクライアントからの接続フローを記載します。

  1. クライアントのユーザプロセスからデータベースサーバのSCANリスナーに対して接続要求を行う
  2. SCANリスナーがローカルリスナーに対してリダイレクトを行う
  3. ローカルリスナーがサーバプロセスの起動を行う
  4. ユーザプロセスとサーバプロセス間で接続が確立される

上記の通り、SCANリスナーの主な役割としてはリクエストをローカルリスナーにリダイレクトするという部分になります。SCANリスナーはリクエストを受け付けると、負荷が低いノードを識別し、そのノードが起動しているローカルリスナーに対してリダイレクトを行います。これはいわゆるサーバ側接続ロードバランシングという仕組みとなります。ちなみにSCANリスナープロセスは最低3つ作成することが推奨されていますので、上の図のように2ノードだったとしてもSCANプロセスは3つ作成することが一般的な構成となります。
Oracle RACにおいてSCANリスナーを使用せずにローカルリスナーにリダイレクトも実施させるサーバ側接続ロードバランシングの仕組みもありますが、以下の理由によりSCANを適用することが推奨されています。

  1. ノード追加、削除などのクラスタ構成変更の際に、クライアントおよびサーバ側の接続設定の変更が不要
  2. サーバ側接続ロードバランシングが自動で適用される
  3. 接続時フェイルオーバが自動で適用される

Oracle RACにおけるノード障害時の挙動

Oracle RAC構成においてノード障害が発生すると、SCANリスナープロセスおよびVIPが正常なノード側にフェイルオーバします。フェイルオーバしている間はリクエストを受け付けられませんが、透過的アプリケーションフェイルオーバ(TAF)という仕組みを適用することで正常なインスタンスに再接続させることが可能です。

  1. 障害が発生したノードのSCANリスナープロセスおよびVIPが正常なノード側にフェイルオーバする
  2. 障害を検知したクライアントは透過的アプリケーションフェイルオーバ機能により正常なノード側へ再接続する

ランタイム接続ロードバランシングを用いたノード間負荷の均一化

上述のようにSCANによる接続ロードバランシングを適用することでクライアントとデータベース間のコネクションは均等に接続されるようになります。ただし、あくまでコネクションが均等になるだけで、そのコネクションを使ったリクエスト(SQL実行数)が均一になるわけではないため、ノード間のリクエスト数(SQL実行数)、リソース使用率に偏りが発生してしまうことがあります。一般的にはコネクションプールを用いて一度確立したコネクションを使いまわすことが多いと思いますので、明示的にコネクションのタイムアウトを設定しない限りは、一度発生した偏りはメンテナンス等で再接続を行うまで継続して発生してしまいます。こういった状況を改善するために、ランタイム接続ロードバランシングという機能がありますので紹介させていただきます。

まず、コネクションプールを使用した処理の概要を下記に記載します。クライアントからのリクエストのたびにコネクション接続の処理が発生すると性能劣化につながることがありますので、一度確立したコネクションをプールしておいて使いまわすのがオンライン処理のおいて一般的に適用される仕組みになります。
下記にコネクションプールの仕組みを適用した際のリクエスト事項の挙動を記載しています。コネクションプールに保持しているコネクションはすべてデータベースと接続していますが、常にすべて使っているわけではなくリクエストが発生した際に一部のコネクションがActive状態になって使われる動きとなります。

接続ロードバランシングによってコネクション数はノード間で均一化されていますので、コネクションプールのコネクションがまんべんなく使用されればノード間で処理するSQL実行数も均一化される挙動となります。しかし、使用されるコネクションに優先順位がついている場合は厄介です。優先的に使用されるコネクションがどちらかのノードに偏っていると、コネクションは均一にも関わらずSQL実行数は偏ってしまう事象が起きる可能性があります。

これを解決してノード間のSQL実行数の偏り、およびリソース使用率の偏りを解消するために有効なのがランタイム接続ロードバランシングという仕組みになります。本仕組みは、RACを構成するインスタンスが負荷の配分を算出し、その情報をクライアント側のコネクションプールに連携します。連携された情報をもとに負荷が小さいインスタンスと接続されているコネクションを多く使用されるような挙動を行います。

下図の通りコネクション数はInstance AとInstance Bで均一ですが、各インスタンスに対する負荷がInstance Aが25%、Instance Bが75%に偏っていたとします。Oracle RACロード・バランシング・アドバイザという機能でインスタンスごとの負荷状態を認識し、情報をコネクションプール側に連携します。ここの情報連携は、高速アプリケーション通知(Fast Application Notification: FAN)と呼ばれる仕組みにて実現されています。

コネクションプールが負荷情報の連携を受けると、負荷が均一になるように使用されるコネクションが選択されるという挙動となります。

以上がランタイム接続ロードバランシングの仕組みでした。本仕組みを用いるにはOracle JDBC Driverを導入する必要がありますのでご留意いただき、適用できるかどうかを検討してみて下さい。

まとめ

ここまで読んでいただきありがとうございました。Oracle RACにおけるデータベース接続、故障時の挙動、負荷分散の手法をご理解いただけたでしょうか。他にもOracle関連の記事をいくつか書いてますので、そちらもぜひご参照ください。

Oracle RACの仕組みを理解しよう ~ClusterwareおよびASMで実現する機能について~
【Oracle】メモリ/ファイルアーキテクチャおよび管理方法についてまとめてみた。
【Oracle】SPFILEに関する情報をまとめてみた。

参考文献

Oracle RACについて
https://www.oracle.com/technetwork/jp/ondemand/db-technique/b-3-rac-1484714-ja.pdf

Oracle Net Serviceについて
https://speakerdeck.com/oracle4engineer/oracle-database-oracle-net-services

SCANリスナーについて
https://www.oracle.com/jp/a/tech/docs/database/scan-ja.pdf

ランタイム接続ロードバランシングについて
https://jpn.nec.com/soft/oracle/files/gc_wp-gridlink-gridcenter-nec.pdf

コメント