ヘッダーをスキップ
Oracle® Coherence開発者ガイド
リリース3.6.1
B61368-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

26 データ・アフィニティ

データ・アフィニティは、関連するキャッシュ・エントリ・グループが単一のキャッシュ・パーティションに含まれることを保証する概念を表します。これにより、フォルト・トレランスを犠牲にすることなく、すべての関連データが単一のプライマリ・キャッシュ・ノードで管理されます。

アフィニティは、(同じキャッシュ・サービスで管理されている通常のケースでは)複数のキャッシュにまたがります。たとえば、Order-LineItemのようなマスター/ディテール・パターンでは、Orderオブジェクトが、関連付けられているLineItemオブジェクトのコレクション全体と共存する場合があります。

これには、2つの利点があります。まず、一連の関連項目に対する問合せおよびトランザクションを、単一のキャッシュ・ノードのみで管理できます。また、すべての並行操作がローカルで管理可能なため、クラスタ化された同期処理が不要です。

アフィニティにより、キャッシュ問合せ、InvocableMapの操作、およびgetAllputAllremoveAllなどのメソッドを含むCoherenceのいくつかの標準的な操作を効率的に実行できます。


注意:

データ・アフィニティは、値ではなくエントリ・キーに関して指定されます。その結果、対応付け情報がキー・クラスに存在している必要があります。同様に、対応付けロジックは、値クラスではなくキー・クラスに適用されます。

アフィニティの指定

アフィニティは、パーティション・キーとの関係で指定されます。前述のOrder-LineItemの例では、Orderオブジェクトが正常にパーティション化され、LineItemオブジェクトは適切なOrderオブジェクトと関連付けられます。

この関連付けは実際の親キーに対して直接実行する必要はなく、親キーの機能マッピングになるだけで十分です。親キーの単一フィールド(一意でない場合でも可能)、または親キーの整数ハッシュとなる場合もあります。重要なのは、すべての子キーで同じ関連キーが返されることだけです。関連キーが実際のキーであるかどうかは重要ではありません(このキーは、単なるグループID)。これにより、親キーの情報を含まない子キー・クラスのサイズの影響を最小限に抑えることができます(導出データであるため、データ・サイズを明示的に決定できるほか、キー動作への影響もありません)。対応付けを汎用化しすぎると(同じグループIDに関連付けられたキーが多すぎる場合)、均一に分散されないことがあります(親キーに関係なく、すべての子キーが同じ関連付けのキーを返した場合、子キーはすべて単一パーティションに割り当てられ、クラスタ全体には分散されません)。

一連のキャッシュ・エントリが同一の場所に配置されることを確認する方法は2つあります。まずこの関連付けが、値ではなく、キャッシュ・キーに基づいていることに注意してください。そうでないと、キャッシュ・エントリの更新に応じてパーティションが変更されることがあります。また、Orderは子のLineItemsと同一の場所に配置されますが、Coherenceでは現在、複数のキャッシュにわたる複合的な操作(たとえば、1つの起動リクエストcom.tangosol.util.InvocableMap.EntryProcessor内におけるOrderの更新とLineItemsの収集)はサポートされていません。

KeyAssociationを使用したデータ・アフィニティの指定

アプリケーション定義のキーでは、キャッシュ・キーのクラスは次のようにcom.tangosol.net.cache.KeyAssociationを実装できます。

例26-1 キーの対応付けの作成

import com.tangosol.net.cache.KeyAssociation;

public class LineItemId implements KeyAssociation
   {
   // {...}

   public Object getAssociatedKey()
       {
       return getOrderId();
       }

   // {...}
   }

KeyAssociatorを使用したデータ・アフィニティの指定

アプリケーションでは、カスタムのKeyAssociatorも指定できます。

例26-2 カスタムのKeyAssociator

import com.tangosol.net.partition.KeyAssociator;

public class LineItemAssociator implements KeyAssociator
    {
    public Object getAssociatedKey(Object oKey)
        {
        if (oKey instanceof LineItemId)
            {
            return ((LineItemId) oKey).getOrderId();
            }
        else if (oKey instanceof OrderId)
            {
            return oKey;
            }
        else
            {
            return null;
            }
        }

    public void init(PartitionedService service)
        {
        }
    }

キー・アソシエータは、NamedCacheに関して、関連付けられている<distributed-scheme>要素で構成できます。

例26-3 キー・アソシエータの構成

<distributed-scheme>
    <!-- ... -->
    <key-associator>
        <class-name>LineItemAssociator</class-name>
    </key-associator>
</distributed-scheme>

アフィニティの使用例

例26-4は、アフィニティを使用してより効率的な問合せ(NamedCache.entrySet(Filter))およびキャッシュ・アクセス(NamedCache.getAll(Collection))を作成する方法を示しています。

例26-4 アフィニティを使用した効率的な問合せの作成

OrderId orderId = new OrderId(1234);

// this Filter will be applied to all LineItem objects to fetch those
// for which getOrderId() returns the specified order identifier
// "select * from LineItem where OrderId = :orderId"Filter filterEq = new EqualsFilter("getOrderId", orderId);

// this Filter will direct the query to the cluster node that currently owns
// the Order object with the given identifier
Filter filterAsc = new KeyAssociatedFilter(filterEq, orderId);

// run the optimized query to get the ChildKey objects
Set setLineItemKeys = cacheLineItems.keySet(filterAsc);

// get all the Child objects immediately
Set setLineItems = cacheLineItems.getAll(setLineItemKeys);
 
// Or remove all immediately
cacheLineItems.keySet().removeAll(setLineItemKeys);