9.4 接続アフィニティについて

この項には次のサブセクションが含まれます:

9.4.1 接続アフィニティの概要

UCP JDBC接続プールは、Oracle RACデータベースが提供するアフィニティ機能を利用します。接続アフィニティには、Oracle JDBCドライバとリリース11.1.0.6以上のOracle RACデータベースを使用する必要があります。

接続アフィニティは、特定のOracle RACインスタンスに送られる接続を接続プールで選択できるようにするパフォーマンス機能です。プールが実行時接続ロード・バランシング(構成されている場合)を使用し、Oracle RACインスタンスを選択して最初の接続を作成すると、後続の接続は同じインスタンスへのアフィニティを使用して作成されます。

関連項目:

UCP JDBC接続プールは、次の3つのタイプの接続アフィニティをサポートします。

9.4.1.1 トランザクションベースのアフィニティ

トランザクションベースのアフィニティは、クライアント・アプリケーションまたは障害イベントによって解放できるOracle RACインスタンスへのアフィニティです。通常、アプリケーションがこのタイプのアフィニティを使用するのは、Oracle RACインスタンスへの存続期間が長いアフィニティが望ましい場合、または新しいOracle RACインスタンスへのリダイレクトのコストが(パフォーマンスの点で)高い場合です。分散トランザクションは、トランザクションベースのアフィニティのよい例です。分散トランザクションに参加しているXA接続は、トランザクション中にOracle RACインスタンスへのアフィニティを保持します。この場合、分散トランザクション中に接続が別のOracle RACインスタンスにリダイレクトされると、アプリケーションで非常に高いパフォーマンス・コストが発生します。

9.4.1.2 Webセッション・アフィニティ

Webセッション・アフィニティは、インスタンス、クライアント・アプリケーションまたは障害イベントによって解放できるOracle RACインスタンスへのアフィニティです。Oracle RACインスタンスは、インスタンスでアフィニティが有効か無効かに関係なく、ヒントを使用して接続プールと通信します。Oracle RACインスタンスは、パフォーマンスやロードなどの様々な要素に基づいてアフィニティを無効にできます。Oracle RACインスタンスでアフィニティがサポートされなくなると、プール内の接続は新しいインスタンスを使用するためにリフレッシュされ、アフィニティが再設定されます。

通常、アプリケーションがこのタイプのアフィニティを使用するのは、Oracle RACインスタンスへの存続期間が短いアフィニティが望ましい場合、または新しいOracle RACインスタンスへのリダイレクトのコストが(パフォーマンスの点で)最も低い場合です。たとえば、メール・クライアント・セッションでは、Oracle RACインスタンスへのWebセッション・アフィニティを使用してパフォーマンスを向上させますが、接続が別のインスタンスにリダイレクトされても相対的に影響を受けません。

9.4.1.3 Oracle RACデータ・アフィニティ

Oracle Databaseリリース18c以降、UCPではOracle RACデータ・アフィニティがサポートされています。Oracle RACデータベースでデータ・アフィニティを有効にすると、アフィニティ設定された表のデータはパーティション化され、表の特定のパーティションまたは行のサブセットが、特定のOracle RACデータベース・インスタンスにアフィニティ設定されます。アフィニティによって、キャッシュ局所性の改善、ノード間の同期化の削減、RACインスタンス間のpingブロックにより、アプリケーションのパフォーマンスおよびスケーラビリティが向上します。

Oracle RACデータ・アフィニティ機能を使用するには、UCPを使用してデータベースにアクセスするクライアントは、接続リクエストでデータ・アフィニティ・キーを指定する必要があります。アフィニティ対応RACデータベースの接続をプールする際に、UCPには次の機能があります。

  1. UCPは、プールの起動時に、Oracle RACインスタンス間のデータ・パーティションのデータ・アフィニティを含むトポロジを認識します。

  2. Oracle RACデータ・アフィニティ機能を利用する必要があるUCP接続リクエストによって、シャーディング・キー・ビルダーを使用してデータ・アフィニティ・キーが指定され、接続ビルダーが次のように使用されます。

      PoolDataSource pds = new PoolDataSourceImpl();
       // configure the datasource with the database connection properties.
    
      OracleShardingKey dataAffinityKey =  pds.createShardingKeyBuilder()
              .subkey(1000, OracleType.NUMBER)
              .build();
          
      Connection connection = pds.createConnectionBuilder()
              .shardingKey(dataAffinityKey)
              .build();

    注意:

    データ・アフィニティ・キーを指定せずに、有効化されたOracle RACデータ・アフィニティへの接続リクエストを行うこともできます。ただし、この場合は、Oracle RACデータ・アフィニティ機能のメリットはありません。

  3. UCPは、リクエストで指定されたシャード・キーに対してアフィニティ設定されたインスタンスを判別し、そのインスタンスの接続がプールに存在するかどうかを確認します。接続が存在する場合は、その接続がリクエストを処理するために使用されます。一致する接続がプールに存在しない場合、実行時ロード・バランシングへのフォールバックにより、リクエストの接続が選択されて処理されます。リクエストを処理するために新しい接続を作成する必要がある場合、リクエストは指定したシャード(データ・アフィニティ)キーに対応する、アフィニティ設定されたインスタンスにルーティングされます。

  4. HAイベントがある場合、またはOracle RACでデータ・パーティションのアフィニティに変更がある場合、UCPは、データ・パーティションのトポロジがサーバー側と同期するようにします。

9.4.2 接続アフィニティの設定

次の手順を実行して、接続アフィニティを設定します。

注意:

トランザクションベースのアフィニティは、アプリケーション/中間層およびUCP間で厳密に有効範囲が指定されます。したがって、トランザクションベースのアフィニティは、setFastConnectionFailoverEnabledプロパティのtrueへの設定のみが必要であり、完全なFCF構成は必要ありません。

また、トランザクションベースのアフィニティは、技術的には実行時接続ロード・バランシングを必要としません。しかし、パフォーマンスの向上に役立つため、通常は有効にしておきます。実行時接続ロードバランシングが無効である場合、接続プールはランダムに接続を選択します。

この項には次のサブセクションが含まれます:

9.4.2.1 接続アフィニティ・コールバックの作成

接続アフィニティには、コールバックを使用する必要があります。コールバックは、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;
      }
   }
}

9.4.2.2 接続アフィニティ・コールバックの登録

接続アフィニティ・コールバックは、registerConnectionAffinityCallbackメソッドを使用して接続プールに登録されます。コールバックは、接続プールの作成時に登録されます。接続プールごとに登録できるコールバックは1つのみです。

次の例では、接続アフィニティ・コールバックの実装の登録を示します。

ConnectionAffinityCallback callback = new MyCallback();

PoolDataSource  pds = PoolDataSourceFactory.getPoolDataSource();

pds.setConnectionPoolName("AffinitySamplePool");
pds.registerConnectionAffinityCallback(callback);
...

9.4.2.3 接続アフィニティ・コールバックの削除

接続アフィニティ・コールバックは、removeConnectionAffinityCallbackメソッドを使用して接続プールから削除されます。次に例を示します。

PoolDataSource  pds = PoolDataSourceFactory.getPoolDataSource();

pds.setConnectionPoolName("AffinitySamplePool");
pds.removeConnectionAffinityCallback();
...

9.4.2.4 厳密なアフィニティ・モード

デフォルトでは、アフィニティはヒントにすぎません。必要なインスタンスの接続が見つからない場合、接続プールは、接続の新しいOracle RACインスタンスを選択します。厳密なアフィニティ・モードをオンに切り替えて、この動作を変更できます。必要なインスタンスの接続が見つからない場合、厳密なアフィニティ・モードはUCP例外をスローします。

次のプール・プロパティを使用して、厳密なアフィニティ・モードをオンに切り替えます。

  • useStrictWebSessionAffinityプロパティ

    厳密なWebセッション・アフィニティ・モードをオンまたはオフに切り替えるには、useStrictWebSessionAffinityプロパティをtrueまたはfalseに設定します。

  • useStrictXAAffinityプロパティ

    厳密なトランザクションベースのアフィニティ・モードをオンまたはオフに切り替えるには、useStrictXAAffinityプロパティをtrueまたはfalseに設定します。

UniversalConnectionPoolMBeanを使用して、これらのプロパティを処理できます。

関連トピック