第2章 Cache API
2.1. Cache API
Cache インターフェースは、エントリーを追加、読み出し、および削除するために簡単なメソッドを提供します。これには JDK の ConcurrentMap
インターフェースによって公開されるアトミックメカニズムが含まれます。エントリーが格納される方法は、使用されるキャッシュモードによって異なります。たとえば、エントリーがリモートノードへレプリケートされたり、キャッシュストアで検索されたりします。
基本的な作業では、キャッシュ API は JDK マップ API と同様に使用されます。そのため、マップベースの簡単なインメモリーキャッシュを Red Hat JBoss Data Grid のキャッシュへ移行する処理が容易になります。
この API は JBoss Data Grid のリモートクライアントサーバーモードでは使用できません。
2.2. ConfigurationBuilder API を使用したキャッシュ API の設定
Red Hat JBoss Data Grid は ConfigurationBuilder API
を使用してキャッシュを設定します。
キャッシュは ConfigurationBuilder
ヘルパーオブジェクトを使用してプログラミングによって設定されます。
以下は、ConfigurationBuilder API
を使用してプログラミングにより設定され、同期的にレプリケートされたキャッシュの例になります。
プログラミングによるキャッシュの設定
Configuration c = new ConfigurationBuilder().clustering().cacheMode(CacheMode.REPL_SYNC).build(); String newCacheName = "repl"; manager.defineConfiguration(newCacheName, c); Cache<String, String> cache = manager.getCache(newCacheName);
-
設定の最初の行で、
ConfigurationBuilder
を使用して新しいキャッシュ設定オブジェクト (c
) が作成されます。設定c
には、キャッシュモードを除くすべてのキャッシュ設定オプションのデフォルト値が割り当てられ、この値は上書きされ、同期レプリケーション (REPL_SYNC
) に設定されます。 -
設定の 2 行目で、新しい変数 (タイプが
String
) が作成され、値repl
が割り当てられます。 -
設定の 3 行目で、キャッシュマネージャーは名前付きキャッシュ設定を定義するために使用されます。この名前付きキャッシュ設定は
repl
と呼ばれ、設定は最初の行のキャッシュ設定c
に提供された設定に基づきます。 -
設定の 4 行目で、キャッシュマネージャーで保持された
repl
の一意のインスタンスに対する参照を取得するために、キャッシュマネージャーが使用されます。このキャッシュインスタンスはデータを格納および取得する操作を実行するために使用できます。
JBoss EAP には独自の基礎となる JMX が含まれています。そのため、JBoss EAP でサンプルコードを使用するときに競合が発生し、org.infinispan.jmx.JmxDomainConflictException: Domain already registered org.infinispan
などのエラーが表示されることがあります。
この問題を回避するには、以下のようにグローバル設定を指定します。
GlobalConfiguration glob = new GlobalConfigurationBuilder() .clusteredDefault() .globalJmxStatistics() .allowDuplicateDomains(true) .enable() .build();
2.3. 呼び出しごとのフラグ
2.3.1. 呼び出しごとのフラグ
Red Hat JBoss Data Grid では呼び出しごとのフラグを使用して各キャッシュコールの動作を指定できます。呼び出しごとのフラグは、時間を節約できる最適化の実装を容易にします。
2.3.2. 呼び出しごとのフラグ機能
Red Hat JBoss Data Grid のキャッシュ API
の putForExternalRead()
メソッドは内部的にフラグを使用します。このメソッドは、外部リソースからロードされたデータが含まれる JBoss Data Grid キャッシュをロードできます。この呼び出しの効率性を改善するために、JBoss Data Grid は通常の put
操作を呼び出して以下のフラグを渡します。
-
ZERO_LOCK_ACQUISITION_TIMEOUT
フラグ: 外部ソースからキャッシュへデータをロードするときに JBoss Data Grid のロック取得時間がほぼゼロになります。 -
FAIL_SILENTLY
フラグ: ロックを取得できない場合に、JBoss Data Grid はロック取得例外を発生せずに失敗します。 -
FORCE_ASYNCHRONOUS
フラグ: クラスター化された場合に、設定されたキャッシュモードに関係なくキャッシュが非同期にレプリケートされます。結果として、他のノードからの応答は必要ありません。
上記のフラグを組み合わせると、操作の効率性が大幅に向上します。この効率性の基礎として、データがメモリーにない場合にクライアントは永続ストアから必要なデータを取得できるため、このタイプの putForExternalRead
コールが使用されます。クライアントはキャッシュミスを検出すると操作を再試行します。
JBoss Data Grid で使用できる全フラグの詳細リストは、JBoss Data Grid API ドキュメントの Flag クラスを参照してください。
2.3.3. 呼び出しごとのフラグの設定
Red Hat JBoss Data Grid で呼び出しごとのフラグを使用するには、withFlags()
メソッド呼び出しを使用して必要なフラグを高度なキャッシュに追加します。
呼び出しごとのフラグの設定
Cache cache = ... cache.getAdvancedCache() .withFlags(Flag.SKIP_CACHE_STORE, Flag.CACHE_MODE_LOCAL) .put("local", "only");
呼び出されたフラグは、キャッシュ操作の間のみアクティブになります。同じトランザクション内の複数の呼び出しで同じフラグを使用するには、各呼び出しに withFlags()
メソッドを使用します。キャッシュ操作を別のノードにレプリケートする必要がある場合は、フラグがリモートノードにも使用されます。
2.3.4. 呼び出しごとのフラグの例
put()
などの書き込み操作が以前の値を返してはならない JBoss Data Grid のユースケースでは、 IGNORE_RETURN_VALUES
フラグが使用されます。このフラグにより分散環境で (以前の値を取得するための) リモート検索が実行されないようにし、不必要な以前の値が取得されないようにします。さらに、キャッシュがキャッシュローダーで設定された場合、このフラグによって以前の値がキャッシュストアからロードされないようにします。
IGNORE_RETURN_VALUES
フラグの使用
Cache cache = ... cache.getAdvancedCache() .withFlags(Flag.IGNORE_RETURN_VALUES) .put("local", "only")
2.4. AdvancedCache インターフェース
2.4.1. AdvancedCache インターフェース
Red Hat JBoss Data Grid は AdvancedCache
インターフェースを提供し、単純な Cache インターフェース以外に JBoss Data Grid を拡張します。 AdvancedCache インターフェースは以下を実行できます。
- カスタマーインターセプターのインジェクト
- 特定の内部コンポーネントへのアクセス
- フラグを適用して特定のキャッシュメソッドの動作を変更
以下のコード例は AdvancedCache
の取得方法の例を示しています。
AdvancedCache advancedCache = cache.getAdvancedCache();
2.4.2. AdvancedCache インターフェースでのフラグの使用
Red Hat JBoss Data Grid の特定のキャッシュメソッドにフラグが適用されると、ターゲットメソッドの動作が変更されます。キャッシュ呼び出しに任意の数のフラグを適用するには、AdvancedCache.withFlags()
を使用します。
フラッグのキャッシュ呼び出しへの適用
advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING) .withFlags(Flag.FORCE_SYNCHRONOUS) .put("hello", "world");
2.4.3. ディストリビューションでの GET および PUT の使用
2.4.3.1. ディストリビューションでの GET および PUT の使用
ディストリビューションモードでは、キャッシュは write コマンドの前にリモートで GET
コマンドを実行します。これは、Cache.put()
などの一部のメソッドは、java.util.Map
コントラクトにしたがって指定されたキーに関連する以前の値を返すためです。これがキーを所有しないインスタンスで実行され、エントリーが L1 キャッシュにない場合、PUT
の前にリモートで GET
を実行することが唯一信頼できる戻り値の取得方法になります。
Red Hat JBoss Data Grid は戻り値を待たなければならないため、キャッシュが同期または非同期であるかに関わらず、 PUT
操作の前に発生する GET
操作は常に同期になります。
2.4.3.2. 分散された GET および PUT 操作のリソース使用
ディストリビューションモードでは、キャッシュが GET
操作を実行してから PUT
操作を実行することがあります。
この操作は、リソースの面では非常にコストのかかる操作になります。リモートの GET
操作は同期であるにも関わらず、すべての応答を待たないため、無駄になるリソースが発生します。 GET
処理は最初に受信する有効な応答を許可するため、パフォーマンスとクラスターの大きさとの関連性はありません。
実装に戻り値が必要でない場合、Flag.SKIP_REMOTE_LOOKUP
フラグを呼び出しごとの設定に使用します。
このような動作は、キャッシュの操作やパブリックメソッドの正確な機能に悪影響を与えるものではありませんが、java.util.Map
インターフェースコントラクトに違反します。これは、信頼できない不正確な戻り値が特定のメソッドに提供されるためコントラクトに違反します。そのため、必ずこれらの戻り値が設定上重要な目的に使用されないようにしてください。
2.4.4. Map メソッドの制限
size()
、values()
、keySet()
、entrySet()
などの特定の Map メソッドは不安定であるため、Red Hat JBoss Data Grid では一定の制限付きで使用することができます。これらのメソッドはロック (グローバルまたはローカル) を取得せず、同時編集、追加、および削除はこれらの呼び出しでは考慮されません。
一覧表示されるメソッドはパフォーマンスに大きく影響します。そのため、情報収集やデバッグの目的でのみこれらのメソッドを使用することが推奨されます。
パフォーマンスの問題
JBoss Data Grid 7.2 では、map メソッド size()
、values()
, keySet()
、および entrySet()
にデフォルトでキャッシュローダーのエントリーが含まれます。これらのコマンドのパフォーマンスは、使用するキャッシュローダーによって決まります。たとえば、データベースを使用している場合、これらのメソッドはデータが格納されるテーブルの完全なスキャンを実行し、処理が遅くなることがあります。キャッシュローダーからエントリーをロードしないようにし、パフォーマンスヒットを避けるには、必要なメソッドを実行する前に Cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD)
を使用します。
size() メソッドの概要 (埋め込みキャッシュ)
JBoss Data Grid 7.2 では、Cache.size()
メソッドは、クラスター全体で、このキャッシュとキャッシュローダーの両方にあるすべての要素の数を提示します。ローダーまたはリモートエントリーを使用している場合、メモリー関連の問題の発生を防げるようにエントリーのサブセットのみが指定時にメモリーに保持されます。すべてのエントリーをロードする場合、その速度が遅くなる場合があります。
この操作モードでは、size()
メソッドで返される結果は、ローカルノードにあるエントリー数を返すよう強制実行する org.infinispan.context.Flag#CACHE_MODE_LOCAL
フラグと、パッシべートされたエントリーを無視する org.infinispan.context.Flag#SKIP_CACHE_LOAD
フラグの影響を受けます。これらのフラグのいずれかを使用すると、クラスター全体ですべての要素の数を返さない代わりにこのメソッドのパフォーマンスを上げることができます。
size() メソッドの概要 (リモートキャッシュ)
JBoss Data Grid 7.1 では、Hot Rod プロトコルには専用の SIZE
操作が含まれ、クライアントはこの操作を使用してすべてのエントリーのサイズを計算します。