この章の内容は次のとおりです。
UCP JDBC接続プールは、様々なOracle Real Application Cluster(RAC)データベース機能と緊密に統合されています。これらの機能には、高速接続フェイルオーバー(FCF)、実行時接続ロード・バランシングおよび接続アフィニティがあります。これらの機能には、Oracle JDBCドライバ、Oracle RACデータベース、Oracle Clientソフトウェアに同梱されているOracle Notification Serviceライブラリ(ons.jar
)を使用する必要があります。これらのテクノロジに精通していない場合は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』および『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。
アプリケーションはOracle RAC機能を使用して、接続のパフォーマンスおよび可用性を最大化し、接続の問題による停止時間を軽減します。アプリケーションの可用性およびパフォーマンスの要件は一様ではないため、それに応じてOracle RAC機能を実装する必要があります。
一般的な高可用性およびパフォーマンスの機能
UCP for JDBC APIおよび接続プールのプロパティには、Oracle RACデータベースを必要としない、多くの高可用性およびパフォーマンスの機能があります。これらの機能は、OracleとOracle以外のどちらの接続とも連携して有効に機能します。これらの機能については、このマニュアル全体を通して説明します。たとえば、流用時の接続の検証、タイムアウト・プロパティの設定、最大再利用プロパティの設定、接続プール・マネージャ操作はすべて、高いレベルの接続の可用性および最適なパフォーマンスを確保するために使用されます。
注意: 一般的な高可用性およびパフォーマンスの機能は、Oracle接続を使用する場合の方がわずかによく機能します。これは、UCP for JDBCがOracle JDBCの内部APIを利用するためです。 |
高速接続フェイルオーバー(FCF)機能は、接続プールを通して実装されるOracle RAC/高速アプリケーション通知(FAN)クライアントです。この機能には、Oracle JDBCドライバおよびOracle RACデータベースを使用する必要があります。この項では、FCFを使用する際にアプリケーションで実行する必要がある手順についてのみ説明します。Oracle RACデータベースの設定の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照するか、Oracleデータベース管理者に問い合せてください。高速接続フェイルオーバーの一般情報は、『Oracle Database JDBC開発者ガイドおよびリファレンス』の「高速接続フェイルオーバー」を参照してください。
FCFは、高可用性のためにプールされた接続を管理します。次の機能があります。
FCFは計画外停止をサポートします。デッド接続はすぐに検出され、中断されてプールから削除されます。接続の削除では、中断が発生するとすみやかにソケット接続を切断し、ハングを回避します。流用された接続および使用中の接続には、計画外停止の場合にのみ割込みが発生します。
FCFで計画停止をサポートします。流用された接続および使用中の接続には、処理が完了して接続の制御がプールに戻るまで、割込みやクローズは発生しません。
FCFは、再試行を確実かつ効果的に行うため、致命的な接続エラーおよび例外をisValid
APIにカプセル化します。このAPIの使用方法は、「接続の有効性のチェック」を参照してください。
FCFは、Oracle RACクラスタに加わる新規ノードを認識して新しい接続を適切に配置し、アプリケーションの実行時に最高品質のサービスを提供します。これにより、Oracle RACノードの追加とアプリケーション層からの作業リクエスト・ルーティングの中間層の統合が容易になります。
FCFは、実行時作業リクエストをすべてのアクティブなOracle RACインスタンスに配布します。
計画外停止のシナリオ
FCFでは、Oracle RACクラスタに対する失効した接続を検出および削除することで、計画外停止のシナリオをサポートします。失効した接続には、サービス停止およびノード停止イベントのために、Oracle RACクラスタのインスタンスで利用できるサービスのない接続が含まれます。流用された接続および使用可能な接続のうち失効しているものが検出され、それらのネットワーク接続が切断されてプールから削除されます。これらの削除された接続は、プールで置き換えられません。かわりに、アプリケーションでは接続を使用して処理を実行する前に、接続を再試行する必要があります。
注意: 流用された接続は、計画外停止のシナリオの際、ただちに中断およびクローズされます。実行中のトランザクションは、即座に例外を受け取ります。 |
計画停止のシナリオ
FCFでは、Oracle RACサービスを適切に停止できる計画停止のシナリオをサポートします。このシナリオの場合、失効している流用された接続にはマークが付けられ、プールに返された後にのみ中断および削除が行われます。実行中のトランザクションに変化はなく、完了するまで続行されます。
計画外停止と計画停止のシナリオの主な違いは、流用された接続の処理方法です。プール内でアイドル状態の(流用されていない)失効した接続は、計画外停止のシナリオと同じ方法で削除されます。
Oracle RACインスタンスの再追加および新しいインスタンスのシナリオ
FCFでは、Oracle RACクラスタが関係するサービスを提供するインスタンスを追加するシナリオをサポートします。インスタンスは、クラスタにとって新しいものでも、停止イベント後に再起動されたものでもかまいません。どちらの場合でも、UCP for JDBCは新しいインスタンスを認識し、必要に応じてノードへの接続を作成します。
次の例では、FCF機能を使用する接続プールを示します。FCFは、プール対応のデータソースを使用して構成されます。この例では、FCFの有効化、Oracle Notification Service(ONS)の構成および接続URLの構成が行われます。これらの項目については、例の後で説明します。
例7-1 高速接続フェイルオーバーの構成の例
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("FCFSamplePool"); pds.setFastConnectionFailoverEnabled(true); pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200\nwalletfile= /oracle11/onswalletfile"); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");pds.setURL("jdbc:oracle:thin@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS=(PROTOCOL=TCP)(HOST=racnode1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=racnode2) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); ...
通常、oracle.ucp.jdbc.ValidConnection
インタフェースのisValid
メソッドはFCF機能とともに使用され、Oracle RAC停止イベントによってSQL例外がスローされた後でも流用された接続が使用可能かどうかをチェックするために使用されます。次に例を示します。
try { conn = pds.getConnection ...}catch (SQLException sqlexc) { if (conn == null || !((ValidConnection) conn).isValid()) // take the appropriate action ... conn.close }
ValidConnection
インタフェースの詳細は、「接続の有効性のチェック」を参照してください。
FCFプール・プロパティを使用して、FCFを有効または無効にします。デフォルトではFCFは無効になっています。次の例では、例7-1に示されているFCFの有効化を示します。
pds.setFastConnectionFailoverEnabled(true);
注意: FCFは、実行時接続ロード・バランシングおよび接続アフィニティを使用する場合にも有効にする必要があります。これらの機能については、この章で後述します。 |
FCFは、Oracle Notification Service(ONS)を利用して、接続プールとOracle RACデータベース間でデータベース・イベントを伝播します。接続プールは、実行時にONS環境を設定できる必要があります。ONS(ons.jar
)はOracle Clientソフトウェアに同梱されています。ONSは、リモート構成またはクライアント側のONSデーモン構成を使用して構成できます。リモート構成は、スタンドアロンのクライアント・アプリケーションに適した構成です。
UCP for JDBCでは、SetONSConfiguration
プール・プロパティを使用したONSのリモート構成をサポートします。ONSプロパティ値は、ons.config
ファイルの内容に酷似している文字列です。この文字列は、改行文字(\n
)で区切られたname=value
ペアのリストからなります。名前は、nodes
、walletfile
、walletpassword
のいずれかです。パラメータ文字列では、少なくともONS構成ノード属性をカンマ区切りのhost:port
ペアのリストとして指定する必要があります。walletfile
属性がOracleウォレット・ファイルとして指定される場合は、SSLが使用されます。
次の例では、例7-1に示されているONS構成文字列を示します。
... pds.setONSConfiguration("nodes=racnode1:4200,racnode2:4200\nwalletfile=/oracle11/onswalletfile"); ...
リモート構成を使用するアプリケーションでは、アプリケーションの起動前にoracle.ons.oraclehome
システム・プロパティをORACLE_HOME
の場所に設定する必要があります。次に例を示します。
java -Doracle.ons.oraclehome=$ORACLE_HOME ...
注意: 構成文字列内のパラメータは、Oracle RACデータベースのパラメータと一致する必要があります。また、setONSConfiguration プロパティは、スタンドアロンのJavaアプリケーションにのみ使用されます。Oracle Application Serverを使用する場合、サーバーに適用される手順を使用してONSを構成する必要があります。 |
クライアント側のONSデーモン構成は、Oracle Application Serverなどの中間層サーバーで実行される典型的なアプリケーションです。このシナリオでのクライアントは、ons.config
ファイルを更新することでONSを直接構成します。ファイルの場所は、プラットフォームによって異なります。次の例では、例7-1用のons.config
ファイルを示します。
localport=4100remoteport=4200nodes=racnode1:4200,racnode2:4200 walletfile=/oracle11/onswalletfile
localport
: ローカル・クライアントと対話するためにlocalhostインタフェースでONSがバインドするポート。
remoteport
: 他のONSデーモンと対話するためにすべてのインタフェースでONSがバインドするポート。
ONSユーティリティ(onsctl
)は、ONSの起動、停止、pingおよびリフレッシュに使用できます。また、ONSのデバッグにも使用できます。ons.config
ファイルの更新後に、ONSをリフレッシュする必要があります。
ONSの設定の詳細は、次を参照してください。
『Oracle Application Server 10g Fast Connection Failover Configuration Guide』
『Oracle Database JDBC開発者ガイドおよびリファレンス』の「高速接続フェイルオーバー」
コネクション・ファクトリの接続URLでは、FCFを使用する際、サービス名の構文を使用する必要があります。サービス名は、接続プールをサービスにマップするために使用されます。また、ファクトリ・クラスはOracleファクトリ・クラスである必要があります。次の例では、例7-1に示されている接続URLの構成を示します。
... pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");pds.setURL("jdbc:oracle:thin@//host:port/service_name"); ...
注意: FCFが有効である場合、サービス識別子(SID)を接続URLに指定すると、例外がスローされます。 |
次の例では、Oracle RACデータベースに接続する際の有効な接続URLの構文を示します。Oracle JDBC ThinドライバとOracle OCIドライバの両方の例が含まれています。URLを使用してOracle RACノード間のロード・バランシングを明示的に有効にできることに注意してください。
有効な接続URLの使用方法
pds.setURL("jdbc:oracle:thin@//host:port/service_name"); pds.setURL("jdbc:oracle:thin@//cluster-alias:port/service_name"); pds.setURL("jdbc:oracle:thin:@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS=(PROTOCOL=TCP)(HOST=host1)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); pds.setURL("jdbc:oracle:thin:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); pds.setURL("jdbc:oracle:oci:@TNS_ALIAS"); pds.setURL("jdbc:oracle:oci:@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))"); pds.setURL("jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))");
UCP JDBC接続プールは、Oracle RACデータベースが提供するロード・バランシング機能を利用します。実行時接続ロード・バランシングには、Oracle JDBCドライバおよびOracle RACデータベースを使用する必要があります。Oracle RACデータベースの設定の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照するか、Oracleデータベース管理者に問い合せてください。
実行時接続ロード・バランシングは、次の場合に便利です。
従来のワークロード・バランシングが最適でない場合
クラスタ・データベース内のリソースを最大限に利用するようにリクエストをルーティングする必要がある場合
クラスタ内の許容量が異なり、時間とともに変化することが予想される場合
低速なノード、ハングアップしたノードおよびデッド・ノードに作業を送信しないようにする要件が必須である場合
UCP for JDBCは、Oracle RACロード・バランシング・アドバイザを使用します。このアドバイザを使用して、Oracle RACインスタンス間の作業のバランスをとり、最高のパフォーマンスを発揮するインスタンスを特定します。アプリケーションは、最高のパフォーマンスを発揮するインスタンスから透過的に接続を受け取ります。速度が落ちたインスタンス、レスポンスを返さないインスタンスまたは障害が発生したインスタンスからは、ただちに接続リクエストが変更されます。
高いパフォーマンスおよびスケーラビリティのためにプールされた接続を管理します。
データベース・インスタンスにルーティングする作業の比率の推奨値を継続的に受け取ります。
CPU性能またはレスポンス時間など、様々なバックエンド・ノードの能力に基づいて作業の分散を調整します。
クラスタ構成の変更、アプリケーション・ワークロード、過度に使用されているノード、ハングアップにすばやく対応します。
Oracle RACロード・バランシング・アドバイザからメトリックを受け取ります。パフォーマンスが良好なインスタンスへの接続が最もよく使用されます。パフォーマンスが低いインスタンスへの新しい未使用の接続は、時間とともに使用されなくなります。分散メトリックを受け取らない場合、接続はランダムに選択されます。
実行時接続ロード・バランシングには、FCFが有効であり、適切に構成されていることが必要です。FCFの設定の詳細は、「高速接続フェイルオーバーの使用方法」を参照してください。
また、ロード・バランシングを有効にする各サービスのサービス・レベルの目標を使用してOracle RACロード・バランシング・アドバイザを構成する必要があります。Oracle RACロード・バランシング・アドバイザは、SERVICE_TIME
またはTHROUGHPUT
に対して構成できます。接続ロード・バランシングの目標は、SHORT
に設定する必要があります。次に例を示します。
EXECUTE DBMS_SERVICE.MODIFY_SERVICE (service_name => 'sjob' -, goal => DBMS_SERVICE.GOAL_THROUGHPUT -, clb_goal => DBMS_SERVICE.CLB_GOAL_SHORT);
または
EXECUTE DBMS_SERVICE.MODIFY_SERVICE (service_name => 'sjob' -, goal => DBMS_SERVICE.GOAL_SERVICE_TIME -, clb_goal => DBMS_SERVICE.CLB_GOAL_SHORT);
ロード・バランシング・アドバイザの目標もDBMS_SERVICE.create_service
をコールして設定できます。『Oracle Real Application Clusters管理およびデプロイメント・ガイド』の「自動ワークロード管理の概要」を参照してください。特に、ロード・バランシング・アドバイザに関する項を参照してください。
UCP JDBC接続プールは、Oracle RACデータベースが提供するアフィニティ機能を利用します。接続アフィニティには、Oracle JDBCドライバとリリース11.1.0.6以上のOracle RACデータベースを使用する必要があります。Oracle RACデータベースの設定の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照するか、Oracleデータベース管理者に問い合せてください。
接続アフィニティは、特定のOracle RACインスタンスに送られる接続を接続プールで選択できるようにするパフォーマンス機能です。プールが実行時接続ロード・バランシング(構成されている場合)を使用し、Oracle RACインスタンスを選択して最初の接続を作成すると、後続の接続は同じインスタンスへのアフィニティを使用して作成されます。
注意: アフィニティはヒントにすぎません。接続プールは、目的のインスタンスが見つからなければ、接続に新しいOracle RACインスタンスを選択します。 |
UCP JDBC接続プールでは、トランザクションベースのアフィニティとWebセッション・アフィニティの2つタイプの接続アフィニティをサポートします。
トランザクションベースのアフィニティ
トランザクションベースのアフィニティは、クライアント・アプリケーションまたは障害イベントによって解放できるOracle RACインスタンスへのアフィニティです。通常、アプリケーションがこのタイプのアフィニティを使用するのは、Oracle RACインスタンスへの存続期間が長いアフィニティが望ましい場合、または新しいOracle RACインスタンスへのリダイレクトのコストが(パフォーマンスの点で)高い場合です。分散トランザクションは、トランザクションベースのアフィニティのよい例です。分散トランザクションに参加しているXA接続は、トランザクション中にOracle RACインスタンスへのアフィニティを保持します。この場合、分散トランザクション中に接続が別のOracle RACインスタンスにリダイレクトされると、アプリケーションで非常に高いパフォーマンス・コストが発生します。
Webセッション・アフィニティは、インスタンス、クライアント・アプリケーションまたは障害イベントによって解放できるOracle RACインスタンスへのアフィニティです。Oracle RACインスタンスは、インスタンスでアフィニティが有効か無効かに関係なく、ヒントを使用して接続プールと通信します。Oracle RACインスタンスは、パフォーマンスやロードなどの様々な要素に基づいてアフィニティを無効にできます。Oracle RACインスタンスでアフィニティがサポートされなくなると、プール内の接続は新しいインスタンスを使用するためにリフレッシュされ、アフィニティが再設定されます。
通常、アプリケーションがこのタイプのアフィニティを使用するのは、Oracle RACインスタンスへの存続期間が短いアフィニティが望ましい場合、または新しいOracle RACインスタンスへのリダイレクトのコストが(パフォーマンスの点で)最も低い場合です。たとえば、メール・クライアント・セッションでは、Oracle RACインスタンスへのWebセッション・アフィニティを使用してパフォーマンスを向上させますが、接続が別のインスタンスにリダイレクトされても相対的に影響を受けません。
FCFを有効にします。「高速接続フェイルオーバーの使用方法」を参照してください。
実行時接続ロード・バランシングを有効にします。「実行時接続ロード・バランシングの使用方法」を参照してください。
接続アフィニティ・コールバックを作成します。
コールバックを登録します。
注意: トランザクションベースのアフィニティは、アプリケーション層/中間層とUCP for JDBC間で厳しくチェックされます。そのため、トランザクションベースのアフィニティではsetFastConnectionFailoverEnabled プロパティをtrue に設定することだけが必要であり、FCFを詳細に構成する必要はありません。
また、トランザクションベースのアフィニティは、技術的には実行時接続ロード・バランシングを必要としません。しかし、パフォーマンスの向上に役立つため、通常は有効にしておきます。実行時接続ロードバランシングが無効である場合、接続プールはランダムに接続を選択します。 |
接続アフィニティには、コールバックを使用する必要があります。コールバックは、oracle.ucp
パッケージにあるConnectionAffinityCallback
インタフェースの実装です。コールバックは、接続アフィニティ・コンテキストを設定および取得するために接続プールで使用されます。また、アフィニティ・ポリシー・タイプ(トランザクションベースまたはWebセッション)の設定にも使用されます。
次の例では、コールバックの実装でのアフィニティ・ポリシーの設定を示します。また、アフィニティ・コンテキストの手動による設定も示します。通常、接続プールがアプリケーション内部でアフィニティ・コンテキストを設定します。しかし、アフィニティの動作をカスタマイズしたりアフィニティ・コンテキストを直接制御するアプリケーションのために、アフィニティ・コンテキストを手動で設定する機能があります。
public class AffinityCallbackSample implements ConnectionAffinityCallback { Object appAffinityContext = null; ConnectionAffinityCallback.AffinityPolicy affinityPolicy = ConnectionAffinityCallback.AffinityPolicy.TRANSACTION_BASED_AFFINITY; //For Web session affinity, use WEBSESSION_BASED_AFFINITY; public void setAffinityPolicy(AffinityPolicy policy) { affinityPolicy = policy; } public AffinityPolicy getAffinityPolicy() { return affinityPolicy; } public boolean setConnectionAffinityContext(Object affCxt) { synchronized (lockObj) { appAffinityContext = affCxt; } return true; } public Object getConnectionAffinityContext() { synchronized (lockObj) { return appAffinityContext; } } }
接続アフィニティ・コールバックは、registerConnectionAffinityCallback
メソッドを使用して接続プールに登録されます。コールバックは、接続プールの作成時に登録されます。接続プールごとに登録できるコールバックは1つのみです。
次の例では、接続アフィニティ・コールバックの実装の登録を示します。
ConnectionAffinityCallback callback = new MyCallback(); PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("AffinitySamplePool"); pds.registerConnectionAffinityCallback(callback); ...
UCP for JDBCは、一連のOracle RACの実行時統計情報を提供します。この統計情報は、接続プールがOracle RAC機能をどの程度利用しているか判断するために使用されます。また、Oracle RAC機能を使用するために接続プールが適切に構成されているかどうかの判断に役立てるためにも使用されます。統計情報には、FCF処理情報、実行時接続ロード・バランスの成否率、アフィニティ・コンテキストの成否率がレポートされます。
oracle.ucp.jdbc.oracle
パッケージにあるOracleJDBCConnectionPoolStatistics
インタフェースは、Oracle RACの統計情報を接続プールに問い合せるために使用されるメソッドを備えています。このインタフェースのメソッドは、データソースのgetStatistics
メソッドを使用して、プール対応のデータソースおよびプール対応のXAデータソースからコールできます。次に例を示します。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); ... Long rclbS = ((OracleJDBCConnectionPoolStatistics)pds.getStatistics()). getSuccessfulRCLBBasedBorrowCount(); System.out.println("The RCLB success rate is "+rclbS+".");
データソースのgetStatistics
メソッドは、それ自身でコールすることも可能であり、接続プールの全統計情報を1つのString
として戻し、Oracle RACの統計情報を組み込みます。
getFCFProcessingInfo
メソッドは、最新のFCFの試行に関する情報をString
の形式で提供します。通常、FCFの情報は、FCFの問題の診断に役立てるために使用されます。この情報は、各FCFの試行結果(成功または失敗)、関連するOracle RACインスタンス、クリーンアップされた接続数、FCFの試行の失敗をトリガーした例外などで構成されます。次の例では、getFCFProcessingInfo
メソッドの使用方法を示します。
Sting fcfInfo = ((OracleJDBCConnectionPoolStatistics)pds.getStatistics()). getFCFProcessingInfo(); System.out.println("The FCF information: "+fcfInfo+".");
実行時接続ロード・バランスの統計情報は、接続プールがOracle RACデータベースの実行時接続ロード・バランシング機能を効率的に利用しているかどうかの判断に使用されます。この統計情報には、実行時接続ロード・バランシングのアルゴリズムを利用できたリクエストの数と、アルゴリズムを利用できなかったリクエストの数がレポートされます。getSuccessfulRCLBBasedBorrowCount
メソッドとgetFailedRCLBBasedBorrowCount
メソッドが、それぞれの統計情報の取得に使用されます。次の例では、getFailedRCLBBasedBorrowCount
メソッドの使用方法を示します。
Long rclbF = ((OracleJDBCConnectionPoolStatistics)pds.getStatistics()). getFailedRCLBBasedBorrowCount(); System.out.println("The RCLB failure rate is: "+rclbF+".");
失敗率が高い場合は、RACロード・バランシング・アドバイザまたは接続プールが適切に構成されていない可能性を示しています。
接続アフィニティの統計情報は、接続プールが接続アフィニティを効率的に利用しているかどうかの判断に使用されます。この統計情報には、アフィニティ・コンテキストと一致した流用リクエストの数と、アフィニティ・コンテキストと一致しなかったリクエストの数がレポートされます。getSuccessfulAffinityBasedBorrowCount
メソッドとgetFailedAffinityBasedBorrowCount
メソッドが、それぞれの統計情報の取得に使用されます。次の例では、getFailedAffinityBasedBorrowCount
メソッドの使用方法を示します。
Long affF = ((OracleJDBCConnectionPoolStatistics)pds.getStatistics()). getFailedAffinityBasedBorrowCount(); System.out.println("The connection affinity failure rate is: "+affF+".");