Coherenceキャッシュからポイント・イン・タイムの問合せ結果を取得でき、その問合せ結果を変更するイベントを受信可能な場合、Coherenceでは、問合せ結果と連続的な関連するイベント・ストリームとを組み合せて、問合せ結果をリアルタイムに維持できます。目的の問合せの待機時間が0である場合と同じ効果を持ち、問合せがミリ秒ごとに数回繰り返されるため、この機能は連続問合せと呼ばれています。ポイント・イン・タイムの問合せ結果およびイベントの詳細は、第6章「キャッシュの問合せ」および「変更発生時のイベントの配信」を参照してください。
Coherenceでは、問合せの結果を連続問合せキャッシュにマテリアライズし、問合せでイベント・リスナーを使用してリアルタイムでキャッシュを最新の状態に保つことにより、連続問合せ機能を実装します。つまり、Coherenceの連続問合せは、決して古くなることのない、キャッシュされた問合せ結果になります。
連続問合せキャッシュには、次のような一般用途のカテゴリがあります。
複合イベント処理(CEP)システムおよびイベント相関エンジンの理想的な構成要素。
アプリケーションで特定の問合せが繰り返され、その問合せの最新の結果に常に即時アクセスできると便利な場合に理想的です。
連続問合せキャッシュはマテリアライズド・ビューとよく似ており、標準的なNamedCache APIを使用して問合せの結果にアクセスおよび操作し、その問合せに関連する一連の進行イベントを受信するのに便利です。
連続問合せキャッシュは、最新のデータ・セットを使用場所(特定のサーバー・ノードやクライアント・デスクトップなど)でローカルに保持できるため、ニア・キャッシュと同様の方法で使用できます。ニア・キャッシュは無効化ベースですが、連続問合せキャッシュでは実際にデータが最新の状態で保持されます。
使用例の1つは取引システムのデスクトップです。このデスクトップでは、トレーダーの未決済のオーダーおよびすべての関連情報を常に最新の状態で保持しておく必要があります。Coherence*Extend機能を連続問合せキャッシュと組み合せることにより、1つのアプリケーションで実際に何万人もの同時ユーザーをサポートできます。
注意: 連続問合せキャッシュは、クライアントベースやサーバーベースのアプリケーションを含む、ほとんどのアプリケーション・タイプで使用可能です。連続問合せキャッシュでは、より大規模で分散されているキャッシュ・データ・セットで、その指定したサブセットの最新ローカル・コピーを非常に簡単かつ効率的に保持できるためです。 |
Coherenceの連続問合せの実装は、com.tangosol.net.cache.ContinuousQueryCache
クラスにあります。このクラスは、Coherenceのすべてのキャッシュと同様に、標準的なNamedCache
インタフェースを実装していますが、これには次の機能が含まれます。
Map
インタフェースを使用したキャッシュのアクセスおよび操作: NamedCache
は、Java Collections Frameworkの標準的なMap
インタフェースを拡張します。これは、JDKのHashMap
クラスとHashtable
クラスで実装されているものと同じインタフェースです。
キャッシュ内で発生するすべてのオブジェクト変更のイベント: NamedCache
は、ObservableMap
インタフェースを拡張します。
キャッシュ内オブジェクトのIDベースのクラスタ全体ロック: NamedCache
は、ConcurrentMap
インタフェースを拡張します。
キャッシュ内オブジェクトの問合せ: NamedCache
は、QueryMapインタフェースを拡張します。
キャッシュ内オブジェクトの分散パラレル処理および集計: NamedCache
は、InvocableMapインタフェースを拡張します。
ContinuousQueryCache
は、Coherenceのすべてのキャッシュと同様にNamedCache
APIインタフェースを実装します。これは、使用方法が簡単で、必要に応じて別のキャッシュの代替機能として利用できます。
連続問合せキャッシュは、次の2つの項目で定義されます。
基礎となるキャッシュ
連続問合せキャッシュでキャッシュされるサブセットを構成する、基礎となるキャッシュの問合せ
基礎となるキャッシュは、別の連続問合せキャッシュを含む、任意のCoherenceキャッシュです。キャッシュは通常、CacheFactory
から取得します。これにより、開発者がキャッシュの名前を指定するだけで、アプリケーションのキャッシュ・コンフィギュレーション情報に基づいてキャッシュが自動的に構成されます。次に例を示します。
NamedCache cache = CacheFactory.getCache("orders");
キャッシュ・コンフィギュレーション情報の指定方法の詳細は、付録D「キャッシュ・コンフィギュレーションの要素」を参照してください。
この問合せは、次の用途で使用される問合せと同じタイプになります。
例3-1 連続問合せキャッシュの問合せ
Filter filter = new AndFilter(new EqualsFilter("getTrader", traderid), new EqualsFilter("getStatus", Status.OPEN));
問合せの詳細は、第6章「キャッシュの問合せ」を参照してください。
通常、キャッシュを問い合せるには、QueryMap
のいずれかのメソッドを使用します。たとえば、このトレーダーのすべてのオープンなトレードのスナップショットを取得するには、次のメソッドを使用します。
同様に、連続問合せキャッシュは次の2つの部分から構成されます。
連続問合せキャッシュを構成するときに、キャッシュが問合せ結果のキーのみを追跡し、リクエストがあった場合にのみ基礎となるキャッシュから値を取得するように指定することができます。この機能は、非常に大きな問合せ結果セットを示す連続問合せキャッシュを作成する場合や、値がまったく、またはほとんどリクエストされない場合に便利です。キーのみをキャッシュするように指定するには、CacheValues
プロパティを構成できるコンストラクタを使用します。次に例を示します。
例3-4 CacheValuesプロパティを構成できるコンストラクタ
ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter, false);
必要に応じて、CacheValues
プロパティはキャッシュがインスタンス化された後で変更することもできます。
連続問合せキャッシュは、それ自体が監視可能であるため、クライアントが1つ以上のイベント・リスナーを配置することができます。次に例を示します。
例3-6 連続問合せキャッシュへのリスナーの追加
ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter); cacheOpenTrades.addMapListener(listener);
キャッシュ内に存在するすべての項目、およびキャッシュに追加されるすべての項目に対してなんらかの処理を行う必要がある場合、次の2つの段階があります。まず、処理を行えるようにします。次に、リスナーを追加して、後から追加された項目を処理できるようにします。
例3-7 連続問合せキャッシュ・エントリの処理とリスナーの追加
ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter); for (Iterator iter = cacheOpenTrades.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); // .. process the cache entry } cacheOpenTrades.addMapListener(listener);
ただし、反復後、リスナーが追加される前のほんの一瞬に発生するイベントが見落とされるため、このコードは正しくありません。かわりに、イベントの見落しがないように、まずリスナーを追加してから処理を行います。
例3-8 リスナー追加後の連続問合せキャッシュ・エントリの処理
ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter); cacheOpenTrades.addMapListener(listener); for (Iterator iter = cacheOpenTrades.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); // .. process the cache entry }
ただし、同じエントリがイベント内とIterator
内の両方に出現し、イベントが非同期になる可能性があるため、操作の順序が正しいことは保証できません。
解決策は、構成時にリスナーを指定することです。そうすることで、既存の(問合せに含まれていた)項目であるか、キャッシュの構成時または構成後に追加された項目かどうかに関係なく、連続問合せキャッシュ内の項目ごとにイベントが1つずつリスナーに送信されます。
例3-9 連続問合せキャッシュ構成時のリスナーの指定
ContinuousQueryCache cacheOpenTrades = new ContinuousQueryCache(cache, filter, listener);
ContinuousQueryCache
実装にも同じ課題がありました。同じキャッシュから変更イベントのストリームを受信しながら、基礎となるキャッシュの正確なポイント・イン・タイム・スナップショットをいかにアセンブルするかということです。この解決策には複数の関係要素があります。まず、Coherenceでは同期イベントのオプションがサポートされており、これによって順序付けが保証されます。このオプションの詳細は、「変更発生時のイベントの配信」を参照してください。
また、ContinuousQueryCache
には初期移入の2フェーズ実装があります。これにより、基礎となるキャッシュを問い合せてから、第1フェーズで発生したすべてのイベントを解決することができます。イベントの見落しや反復なしでデータの可視性を保証することはかなり困難であるため、ContinuousQueryCache
では、開発者が構成時にリスナーを渡すことができます。これにより、アプリケーション開発者は同様の複雑な作業をする必要はありません。