14 ストレージおよびバッキング・マップの実装

Coherenceでは、バッキング・マップを使用してデータが格納されます。様々なバッキング・マップ実装から選択でき、バッキング・マップ実装はアプリケーションでの必要に応じて構成できます。

この章の内容は次のとおりです。

キャッシュ・レイヤー

Coherenceのパーティション化された(分散型)キャッシュ・サービスには、データの格納に使用される3つの異なるレイヤーがあります。
  • クライアント・ビュー - 基礎となるパーティション化されたデータへのアクセスを可能にする仮想レイヤー。この層へのアクセスには、 NamedCacheインタフェースが使用されます。このレイヤーでは、NearCacheContinuousQueryCacheなどの統合データ構造も作成できます。

  • ストレージ・マネージャ - クライアント層からのキャッシュ関連リクエストを処理するサーバー側の層です。実際のキャッシュ・データ(プライマリ・コピーおよびバックアップ・コピー)、およびロック、イベント・リスナー、マップ・トリガーなどに関する情報を格納するデータ構造を管理します。

  • バッキング・マップ - 実際のデータを格納するサーバー側のデータ構造。

Coherenceでは、即時利用可能なバッキング・マップ実装およびカスタム実装を構成できます。マップ実装における唯一の制約は、ストレージ・マネージャではキーと値がすべて内部(バイナリ)形式で指定されるという点を理解することです。内部データとオブジェクト形式との間の変換を処理するため、ストレージ・マネージャでは、BackingMapManagerContext参照によるバッキング・マップの実装が可能です。

図14-1はバッキング・マップの概念図です。

図14-1 バッキング・マップの記憶域

図14-1の説明が続きます
「図14-1 バッキング・マップの記憶域」の説明

ローカル記憶域

ローカル記憶域は、Coherenceで管理されるデータを実際に保存またはキャッシュするデータ構造です。
ローカル記憶域を提供するオブジェクトは、同じ標準のコレクション・インタフェースであるjava.util.Mapをサポートする必要があります。Coherenceのローカル記憶域の実装を使用して、レプリケートされたデータや分散データを保存する場合、その機能をバッキング・マップと呼びます。これは、Coherenceがローカル記憶域の実装によって実際に支援(バックアップ)されるためです。その他、ローカル記憶域の一般的な使用法としては、分散キャッシュの前に配置したり、分散キャッシュの後方でバックアップを行うことがあります。

注意:

データをヒープに格納しないバッキング・マップを使用する際には注意してください。特に、実際にヒープに収めるには格納データが多すぎる場合が当てはまります。あるキャッシュ操作(索引なしの問合せなど)では、多数のエントリが横断される可能性があります。これにより、バッキング・マップがそれらのエントリをヒープに格納するようになります。また、パーティション転送(バックアップからのリストアや新規メンバーが参加した場合のパーティション所有権の転送など)によって、バッキング・マップが多数のエントリをヒープに格納するようになります。これは、GC問題とOutOfMemoryエラーの発生の原因になる可能性があります。

Coherenceは、次のローカル記憶域の実装をサポートします。

  • セーフなHashMap: デフォルトのロスレス実装です。ロスレス実装には、JavaのHashtableクラス同様、サイズ制限も自動失効もありません。つまり、自身に含まれるキャッシュ項目を削除する(損失する)ことのない実装です。この特殊なHashMap実装は、非常に高度なスレッドレベルの並行性にあわせて最適化されていますデフォルト実装にはcom.tangosol.util.SafeHashMapクラスを、キャッシュ・イベントの送信が必要な実装にはcom.tangosol.util.ObservableHashMapを使用します。これらの実装はスレッドセーフです。

  • ローカル・キャッシュ: デフォルトのサイズ制限および自動失効の実装です。キャパシティ・プランニングを参照してください。ローカル・キャッシュでは、キャッシュのサイズが制限されており、特定の期間の経過後にキャッシュ・アイテムが自動的に期限切れします。デフォルト実装にはcom.tangosol.net.cache.LocalCacheを使用します。この実装はスレッド・セーフであり、キャッシュ・イベント、com.tangosol.net.CacheLoaderCacheStore、および構成可能でプラガブルなエビクション・ポリシーがサポートされます。

  • 読取り/書込みバッキング・マップ: これは、キャッシュ・ミスの際にバッキング・ストア(データベースなど)からロードする、キャッシュのデフォルトのバッキング・マップの実装です。これは、読取り専用キャッシュ(コンシューマ・モデル)として構成することも、ライトスルーまたはライトビハインド・キャッシュ(コンシューマ/プロデューサ・モデル)として構成することもできます。ライトスルーおよびライトビハインド・モードは、分散キャッシュ・サービスで使用することのみを目的としています。ニア・キャッシュとともに使用する場合、ニア・キャッシュと分散キャッシュの同期を維持する必要があるのであれば、(ニア・キャッシュを無効化する目的で)このバッキング・マップをSeppukuベースのニア・キャッシュと組み合せて使用できます。デフォルト実装にはcom.tangosol.net.cache.ReadWriteBackingMapクラスを使用します。

  • バイナリ・マップ(Java NIO): 自身の情報をJavaヒープ外のメモリー・マップ・ファイルに保存できるバッキング・マップ実装で、Javaヒープ・サイズには影響せず、アプリケーションの一時停止の原因となり得る関連したJVMガベージ・コレクションのパフォーマンスにも影響しないことを意味します。この実装はまた、分散キャッシュのバックアップにも使用できます。これは高可用性を実現するためにバックアップを必要とする、読取り専用(または読取りを主体とする)キャッシュで特に有用です。このバックアップがJavaヒープ・サイズに影響しないにもかかわらず、フェイルオーバー時には瞬時に使用できるためです。

  • シリアライズ・マップ: これは、ディスクに保存できる形式にデータを変換するバッキング・マップの実装です。この形式は、シリアライズされた形式と呼ばれています。これには、シリアライズ形式のデータを格納する別個のcom.tangosol.io.BinaryStoreオブジェクトが必要です。シリアライズ・マップは、BinaryStoreのすべてのカスタム実装をサポートします。シリアライズ・マップのデフォルト実装にはcom.tangosol.net.cache.SerializationMapを使用します。

  • シリアライズ・キャッシュ: LRUエビクション・ポリシーをサポートするSerializationMapの拡張機能です。たとえば、シリアライズ・キャッシュによって、ディスク・ファイルのサイズを制限できます。シリアライズ・キャッシュのデフォルト実装にはcom.tangosol.net.cache.SerializationCacheを使用します。

  • ジャーナル: これは、RAM、ディスクのいずれかまたは両方にデータを格納するバッキング・マップの実装です。ジャーナルには、com.tangosol.io.journal.JournalBinaryStoreクラスが使用されます。エラスティック・データ機能を使用したデータの保存を参照してください。

  • オーバーフロー・マップ: オーバーフロー・マップは実際には記憶域を提供しませんが、2つのローカル記憶域の実装を結合し、最初の記憶域が一杯になると、オーバーフローを行って次の記憶域にデータを保存することから、この項で紹介していますOverflowMapのデフォルト実装にはcom.tangosol.net.cache.OverflowMapを使用します。

  • カスタム・マップ: これは、java.util.Mapインタフェースに準拠するバッキング・マップ実装です。

    たとえば:

    <backing-map-scheme>
       <class-scheme>
          <class-name>com.tangosol.util.SafeHashMap</class-name>
       </class-scheme>
    </backing-map-scheme>

    ノート:

    使用するバッキング・マップ実装に関係なく、マップはスレッド・セーフである必要があります。

操作

バッキング・マップに対して実行される操作にはいくつかのタイプがあります。次の操作があります。
  • アプリケーションの使用によって必然的に発生するアクセスおよび更新操作。たとえば、NamedCache.get()コールでは対応するバッキング・マップに対するMap.get()コールが発生します。また、NamedCache.invoke()コールではMap.get()とそれに続くMap.put()が発生する場合があり、NamedCache.keySet(filter)コールではMap.entrySet().iterator()ループが発生する場合があります。

  • 時間ベースの有効期限またはサイズ・ベースのエビクションによって発生する削除操作。たとえば、クライアント層からのNamedCache.get()コールまたはNamedCache.size()コールでは、エントリの有効期限切れによるMap.remove()コールが発生する場合があります。また、NamedCache.put()コールでは、バッキング・マップの合計データ量が構成済の高水位標値に達した場合に、複数のMap.remove()コールが(複数のキーに対して)発生する場合があります。

  • CacheStore.load()操作によって発生する挿入操作(リードスルー機能またはリードアヘッド機能が構成されたバッキング・マップの場合)

  • パーティション分散によって発生する統合アクセスおよび更新(クラスタ・ノードのフェイルオーバーまたはフェイルバックから発生する場合もあります)。この場合は、アプリケーション層のコールがなくても、バッキング・マップのいくつかのエントリが挿入または削除されることがあります。

キャパシティ・プランニング

データ・グリッドに配置されるデータの総量は、あらかじめ決められたメモリー量を超えることはできません。アプリケーションは、アプリケーション層のロジックを介してデータの総量を直接管理することも、サイズ・ベースまたは期限切れベースのエビクションを使用した自動管理に任せることもできます。バッキング・マップは、バッキング・マップの実装(ヒープ、ディスクおよびソリッド・ステートのオンまたはオフ)に応じて、いくつかの方法でキャッシュ・データを保存できます。データをメモリーに格納することで、アクセスおよび更新の待機時間が大幅に短縮されます。また、これは最も一般的に使用される方法でもあります。

その結果、Coherenceのキャッシュに保持されるデータの合計量は、対応するすべてのバッキング・マップ(対応するパーティション・キャッシュ・サービスを記憶域有効モードで実行するクラスタ・ノードごとに1つ)のデータの合計量と等しくなります。

次のキャッシュ構成の抜粋について検討してみましょう:

<backing-map-scheme>
  <local-scheme/>
</backing-map-scheme>

このバッキング・マップはcom.tangosol.net.cache.LocalCacheのインスタンスであり、事前設定されたサイズの制約がなく、明示的に制御する必要があります。制御できない場合は、JVMがメモリー不足になります。次の例では、バッキング・マップのサイズの制約を構成します。

<backing-map-scheme>
  <local-scheme>
    <eviction-policy>LRU</eviction-policy>
    <high-units>100M</high-units>
    <unit-calculator>BINARY</unit-calculator>
  </local-scheme>
</backing-map-scheme>

このバッキング・マップもcom.tangosol.net.cache.LocalCacheですが、100MBの容量制限があります。<high-units>に単位が指定されていない場合、デフォルトはbyteです。<high-units>を参照してください。<unit-factor>は、次の例に示すように、指定することもできます:

<backing-map-scheme>
  <local-scheme>
    <eviction-policy>LRU</eviction-policy>
    <high-units>100</high-units>
    <unit-calculator>BINARY</unit-calculator>
    <unit-factor>1000000</unit-factor>
  </local-scheme>
</backing-map-scheme>

このバッキング・マップで保持されるデータの合計量が高水位標を超えると、バッキング・マップから一部のエントリが削除され、データの量が低水位標値(<low-units>構成要素、デフォルトでは<high-units>の80%)まで減少します。値がInteger.MAX_VALUEを超えると、ユニット・ファクタが自動的に使用され、それ応じて<high-units>および<low-units>値が調整されます。削除されるエントリの選択方法は、LRU(最低使用頻度)エビクション・ポリシーに従います。その他のオプションには、LFU(最低アクセス頻度)および混合(LRUとLFUの組合せ)があります。

次のバッキング・マップは、未更新の状態のまま1時間を超えたエントリを自動的に削除します。1時間を超えるエントリはコール元には返されません。次のキャッシュ操作が実行されるとき、または次のスケジュール済デーモンEvictionTaskが実行されるときに、キャッシュから遅延削除されます。EvictionTaskデーモンのスケジュールは、キャッシュ失効の遅延によって異なります。最小間隔は250ミリ秒です。

<backing-map-scheme>
  <local-scheme>
    <expiry-delay>1h</expiry-delay>
  </local-scheme>
</backing-map-scheme>

分散スキーム内のバッキング・マップはスライディング失効もサポートしています。有効な場合:

  • 読取り操作により、アクセスされるキャッシュ・エントリの有効期限が延長されます。読取り操作には、getgetAllinvokeおよびinvokeAllが含まれ、エントリは変更されません(たとえば、エントリ・プロセッサのentry.getValueのみ)。

  • 変更されない参加済のエントリ(たとえば、インターセプタまたはトリガーから)の有効期限も延長されます。

  • 操作が読取りアクセスのみの場合、バックアップ(有効期限が変更される場合)は非同期で実行されます。変更操作が含まれる場合(たとえば、putまたはputAll操作中にエビクションが発生)、バックアップは同期で実行されます。

ノート:

スライディング失効は、aggregatequery操作などの問合せリクエストに基づいてアクセスされるエントリに対しては実行されません。

スライディング失効を有効にするには、<backing-map-scheme>要素内で<sliding-expiry>要素をtrueに設定し、<expiry-delay>要素がゼロより大きい値に設定されていることを確認します。たとえば、

<distributed-scheme>
   <scheme-name>dist-expiry</scheme-name>
   <service-name>DistributedExpiry</service-name>
   <backing-map-scheme>
      <sliding-expiry>true</sliding-expiry>
      <local-scheme>
         <expiry-delay>3s</expiry-delay>
      </local-scheme>
   </backing-map-scheme>
</distributed-scheme>

パーティション・バッキング・マップの使用

Coherenceでは、デフォルトのバッキング・マップ実装とは異なる、パーティション化されたバッキング・マップ実装が提供されます。従来のバッキング・マップの実装では、対応するノードが所有するすべてのパーティションのエントリが格納されます。パーティション送信時に、クライアントから見て一時的に所有者の存在しない未完了エントリも保持されることがありました。

図14-2は、従来のバッキング・マップ実装の概念図です。

図14-2 従来のバッキング・マップの実装

図14-2の説明が続きます
「図14-2 従来のバッキング・マップの実装」の説明

パーティション・バッキング・マップは、実際のMap実装の多重化であり、それぞれのマップには同じパーティションに属するエントリのみが格納されます。パーティション・バッキング・マップは、記憶域の上限(java.util.Map APIで発生)をバッキング・マップの2Gから各パーティションの2Gに上げます。パーティション・バッキング・マップは、一般にソリューションが2Gのバッキング・マップの上限に達すると使用され、多くの場合、エラスティック・データ機能の使用時に可能になります。エラスティック・データ機能を使用したデータの保存を参照してください。

図14-3は、パーティション・バッキング・マップ実装の概念図です。

図14-3 パーティション・バッキング・マップの実装

図14-3の説明が続きます
「図14-3 パーティション・バッキング・マップの実装」の説明

パーティション・バッキング・マップを構成するには、<partitioned>要素を、値をtrueに設定して追加します。たとえば:

<backing-map-scheme>
  <partitioned>true</partitioned>
  <external-scheme>
    <nio-memory-manager>
      <initial-size>1MB</initial-size>
      <maximum-size>50MB</maximum-size>
    </nio-memory-manager>
    <high-units>8192</high-units>
    <unit-calculator>BINARY</unit-calculator>
  </external-scheme>
</backing-map-scheme>

このバッキング・マップはcom.tangosol.net.partition.PartitionSplittingBackingMapのインスタンスであり、マップを保持する個別のパーティションであるcom.tangosol.net.cache.SerializationCacheのインスタンスから構成され、各パーティションの拡張(nio)メモリーに値が格納されます。nioバッファにはそれぞれ50MBの制限がありますが、バッキング・マップ全体の容量制限は8GB (8192*1048576)です。

エラスティック・データ機能を使用したデータの保存

エラスティック・データ機能は、メモリーとディスクベースのデバイス間で、シームレスにデータを保存するために使用されます。この機能は、特にSSD (Solid State Disk)などの高速ディスクベースのデバイスを使用する場合に調整され、SSDからデータを読書きする際にメモリーと同等の速度でアクセスできるようにします。エラスティック・データ機能では、ジャーナルという技術を使用して、メモリーとディスク間の保存操作を最適化します。

エラスティック・データには、メモリー内にデータを保存するRAMジャーナルと、ディスクベースのデバイスにデータを保存するフラッシュ・ジャーナルという2つのコンポーネントが含まれます。これらを様々に組み合せ、一般的にはバッキング・マップやバックアップ記憶域に使用しますが、複合キャッシュにも使用できます(たとえば、ニア・キャッシュなど)。RAMジャーナルは、フラッシュ・ジャーナルとともに機能し、ディスクへのシームレスなオーバーフローを実現します。

RAMジャーナルおよびフラッシュ・ジャーナルを使用するキャッシュは、キャッシュ構成ファイル内にキャッシュ・スキーム定義の一部として構成されます。必要に応じて、オペレーション・オーバーライド・ファイルを使用して初期状態の構成をオーバーライドし、ジャーナルの動作を構成します。

この項には次のトピックが含まれます:

ジャーナルの概要

ジャーナル機能とは、ジャーナルと呼ばれる一連の変更において状態の変化を記録する技術です。変更が発生すると、ジャーナルは特定のキーの各値を記録し、メモリー内に保存されるツリー構造により、特定のキーの現在の値を含むジャーナル・エントリが追跡されます。エントリの値を検索するには、最新の値を含むジャーナル・エントリへのポインタを含むツリーでキーを検索します。

キーに新しい値が書き込まれることによりジャーナルの変更情報が古くなると、ジャーナルには古い値が累積されます。一定の間隔で古い値を削除すると、新しい値をジャーナルに書き込むスペースができます。

エラスティック・データ機能には、RAMジャーナル実装とフラッシュ・ジャーナル実装が含まれ、相互にシームレスに機能します。たとえば、RAMジャーナルでメモリーを使用し尽くした場合、フラッシュ・ジャーナルがRAMジャーナルからのオーバーフローを自動的に受け入れ、キャッシュをRAMのサイズより格段に大きなサイズにまで拡張できます。

ノート:

エラスティック・データはキーベース操作を実行する際には理想的ですが、一般的に大規模なフィルタベース操作での使用はお薦めしません。ジャーナルを有効にした場合、大きな結果セットでデータ・グリッド操作(問合せや集計など)を実行する際に追加のキャパシティ・プランニングが必要になります。Oracle Coherenceの管理一般的なガイドラインを参照してください。

リソース・マネージャはジャーナルを制御します。リソース・マネージャはバイナリ・ストアを作成および使用して、ジャーナルの操作を実行します。バイナリ・ストアは、JournalBinaryStoreクラスで実装されます。バイナリ・ストアを介したすべての読書きは、リソース・マネージャで処理されます。RAMジャーナル用のリソース・マネージャ(RamJournalRM)とフラッシュ・ジャーナル用のリソース・マネージャ(FlashJournalRM)があります。

ジャーナル・スキームの定義

キャッシュ構成ファイルでは、<ramjournal-scheme>および<flashjournal-scheme>要素を使用して、それぞれRAMジャーナルおよびフラッシュ・ジャーナルを構成します。ramjournal-schemeおよびflashjournal-schemeを参照してください。

この項には次のトピックが含まれます:

RAMジャーナル・バッキング・マップの構成

RAMジャーナル・バッキング・マップを構成するには、キャッシュ定義の<backing-map-scheme>要素の中に<ramjournal-scheme>要素を追加します。次の例では、バッキング・マップにRAMジャーナルを使用する分散キャッシュを作成します。RAMジャーナルは、構成されたメモリー・サイズを超えると、自動的にフラッシュ・ジャーナルに委任します。ジャーナルの動作の変更を参照してください。

<distributed-scheme>
   <scheme-name>distributed-journal</scheme-name>
   <service-name>DistributedCacheRAMJournal</service-name>
   <backing-map-scheme>
      <ramjournal-scheme/>
   </backing-map-scheme>
   <autostart>true</autostart>
</distributed-scheme>
フラッシュ・ジャーナル・バッキング・マップの構成

フラッシュ・ジャーナル・バッキング・マップを構成するには、キャッシュ定義の<backing-map-scheme>要素の中に<flashjournal-scheme>要素を追加します。次の例では、バッキング・マップにフラッシュ・ジャーナルを使用する分散スキームを作成します。

<distributed-scheme>
   <scheme-name>distributed-journal</scheme-name>
   <service-name>DistributedCacheFlashJournal</service-name>
   <backing-map-scheme>
      <flashjournal-scheme/>
   </backing-map-scheme>
   <autostart>true</autostart>
</distributed-scheme>
ジャーナル・スキームの参照

RAMジャーナル・スキームおよびフラッシュ・ジャーナル・スキームでは、スキーム定義を再利用するためのスキーム参照の使用をサポートします。次の例では、default-ramというRAMスキーム定義を参照することで、分散キャッシュを作成して、RAMジャーナル・バッキング・マップを構成しています。

<caching-schemes>
   <distributed-scheme>
      <scheme-name>distributed-journal</scheme-name>
         <service-name>DistributedCacheJournal</service-name>
         <backing-map-scheme>
            <ramjournal-scheme>
               <scheme-ref>default-ram</scheme-ref>
            </ramjournal-scheme>
         </backing-map-scheme>
         <autostart>true</autostart>
   </distributed-scheme>

   <ramjournal-scheme>
      <scheme-name>default-ram</scheme-name>
   </ramjournal-scheme>
</caching-schemes>
ジャーナルの失効およびエビクションの使用

RAMジャーナルおよびフラッシュ・ジャーナルはサイズを制限できます。保存するエントリ数を制限し、ジャーナルが一杯になったらエントリを自動的に削除できます。さらに、エントリのサイジングとエビクション・ポリシーの両方のカスタマイズが可能です。次の例では、RAMジャーナルの失効およびエビクション設定を定義しています。

<distributed-scheme>
   <scheme-name>distributed-journal</scheme-name>
   <service-name>DistributedCacheFlashJournal</service-name>
   <backing-map-scheme>
      <ramjournal-scheme>
         <eviction-policy>LFU</eviction-policy>
         <high-units>100</high-units>
         <low-units>80</low-units>
         <unit-calculator>Binary</unit-calculator>
         <expiry-delay>0</expiry-delay>
      </ramjournal-scheme>
   </backing-map-scheme>
   <autostart>true</autostart>
</distributed-scheme>
バックアップ記憶域でのジャーナル・スキームの使用

ジャーナル・スキームは、バックアップ記憶域およびバッキング・マップに使用されます。デフォルトでは、バッキング記憶域としてフラッシュ・ジャーナルが使用されます。このデフォルトの動作は、<backup-storage>要素の中のストレージ・タイプを明示的に指定することで、変更できます。次の構成ではバッキング・マップにRAMジャーナルを使用し、明示的にバックアップ記憶域にRAMジャーナルを構成しています。

<caching-schemes>
   <distributed-scheme>
      <scheme-name>default-distributed-journal</scheme-name>
         <service-name>DistributedCacheJournal</service-name>
         <backup-storage>
            <type>scheme</type>
            <scheme-name>example-ram</scheme-name>
         </backup-storage>
         <backing-map-scheme>
            <ramjournal-scheme/>
         </backing-map-scheme>
      <autostart>true</autostart>
   </distributed-scheme>

   <ramjournal-scheme>
      <scheme-name>example-ram</scheme-name>
   </ramjournal-scheme>
</caching-schemes>
ジャーナル・スキームでのカスタム・マップ実装の有効化

必要に応じて、カスタム・バッキング・マップを使用するようにジャーナル・スキームを構成できます。カスタム・マップ実装では、CompactSerializationCacheクラスを拡張し、完全に同一のpublicなコンストラクタのセットを宣言する必要があります。

カスタム実装を有効にするには、<class-scheme>要素を追加し、その値をカスタム・クラスの完全修飾名に指定します。カスタム・クラスに必要な任意のパラメータは、<init-params>要素を使用して定義できます。次の例では、MyCompactSerializationCacheというカスタム・マップ実装を有効にします。

<flashjournal-scheme>
   <scheme-name>example-flash</scheme-name>
   <class-name>package.MyCompactSerializationCache</class-name>
</flashjournal-scheme>

ジャーナルの動作の変更

リソース・マネージャはジャーナルの動作を制御します。RAMジャーナル用のリソース・マネージャ(RamJournalRM)とフラッシュ・ジャーナル用のリソース・マネージャ(FlashJournalRM)があります。クラスタのリソース・マネージャは、tangosol-coherence-override.xmlオペレーション・オーバーライド・ファイルで構成されます。構成オーバーライドが設定されていないと、リソース・マネージャのデフォルトの即時利用可能な設定が使用されます。

この項には次のトピックが含まれます:

RAMジャーナル・リソース・マネージャの構成

<ramjournal-manager>要素は、RAMジャーナルの動作を構成するために使用されます。次のリストは、RAMジャーナルのデフォルト特性を示しています。ramjournal-managerを参照してください。

  • バイナリ値は、デフォルトでは64KBに制限されています(最大は4MB)。フラッシュ・ジャーナルは、バイナリ値が構成済制限を超えると自動的に使用されます。

  • 個々のバッファ(ジャーナル・ファイル)は、デフォルトでは2MBに制限されています(最大は2GB)。最大ファイル・サイズは変更しないでください。

  • ジャーナルは最大512個のファイルで構成されています。511個のファイルは使用可能なファイルで、1個のファイルはデプリート状態ために予約されています。

  • ジャーナルで使用される合計メモリーは、デフォルトでは1GBに制限されています(最大は64GB)。フラッシュ・ジャーナルは、ジャーナルの合計メモリーが構成済制限を超えると自動的に使用されます。

RAMジャーナル・リソース・マネージャを構成するには、<ramjournal-manager>要素を<journaling-config>要素の中に追加して、オーバーライドするサブ要素を定義します。次の例では、RAMジャーナル・サブ要素のオーバーライドを示しています。

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config
   coherence-operational-config.xsd">
   <cluster-config>
      <journaling-config>
         <ramjournal-manager>
            <maximum-value-size>64K</maximum-value-size>
            <maximum-size system-property="coherence.ramjournal.size">2G</maximum-size>
         </ramjournal-manager>
      </journaling-config>
   </cluster-config>
</coherence>
フラッシュ・ジャーナル・リソース・マネージャの構成

<flashjournal-manager>要素は、フラッシュ・ジャーナルの動作を構成するために使用されます。次のリストは、フラッシュ・ジャーナルのデフォルト特性を示しています。flashjournal-managerを参照してください。

  • バイナリ値は、デフォルトでは64MBに制限されています。

  • 個々のバッファ(ジャーナル・ファイル)は、デフォルトでは2GBに制限されています(最大は4GB)。

  • ジャーナルは最大512個のファイルで構成されています。511個のファイルは使用可能なファイルで、1個のファイルはデプリート状態ために予約されています。ジャーナルはデフォルトでは1TBに制限され、理論上最大2TBとなります。

  • ジャーナルには、デフォルトで11GBの高いジャーナル・サイズが設定されています。この高いサイズによって、ジャーナルから失効した値の削除を開始するタイミングが決定されます。これは、ジャーナル・サイズの強い制限ではなく、依然として最大ファイル数(512)まで大きくなることができます。

  • キーは、圧縮された形式でメモリー内に残ります。値については、書き込まれていない(キューに入れられているか非同期に書き込まれる)データのみがメモリーに残ります。ヒープのサイズを決定するときの合理的な見積りは、キー・データを保持するエントリごとに50バイトを許可し(これは、RAMとフラッシュの両方のジャーナルに当てはまります)、バッファ用の追加の容量(16MB)を含めることです。失効またはエビクションを構成すると、エントリ・サイズは増加します。

  • フラッシュ・ジャーナルは、RAMジャーナルの容量に到達すると、オーバーフローとして自動的に使用されます。フラッシュ・ジャーナルは、フラッシュ・ジャーナルの最大サイズを0 (ジャーナルがRAMジャーナルを排他的に使用)に設定することで無効にできます。

フラッシュ・ジャーナル・リソース・マネージャを構成するには、<flashjournal-manager>要素を<journaling-config>要素の中に追加して、オーバーライドするサブ要素を定義します。次の例では、フラッシュ・ジャーナル・サブ要素のオーバーライドを示しています。

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config
   coherence-operational-config.xsd">
   <cluster-config>
      <journaling-config>
         <flashjournal-manager>
            <maximum-size>100G</maximum-size>
            <directory>/coherence_storage</directory>
         </flashjournal-manager>
      </journaling-config>
   </cluster-config>
</coherence>

ノート:

ジャーナル・ファイルを保存するために指定されたディレクトリが存在する必要があります。ディレクトリが存在しない場合、警告がログに記録され、JVMで指定されたデフォルトの一時ファイル・ディレクトリが使用されます。

非同期バックアップの使用

分散キャッシュでは、同期と非同期の両方のバックアップがサポートされています。同期バックアップでは、バックアップ操作が完了するまでクライアントがブロックされます。非同期バックアップでは、バックアップ操作中にクライアントはリクエストへの応答を続行します。バックアップは、非同期バックアップが明示的に有効化されていないかぎり、同期で実行されます。

非同期バックアップは、通常、クライアントのパフォーマンスを向上させるために使用されます。ただし、非同期バックアップを使用するアプリケーションは、データの整合性に対して発生しうる影響に対処する必要があります。特に、バックアップ操作が(成功または失敗して)完了する前にキャッシュ操作が完了する場合があり、バックアップ操作の完了順序は決まっていません。アプリケーションでバックアップが不要な場合(つまり、損失したデータを記録システムからリストアできる場合)は、非同期バックアップの使用を検討してください。しかし、この場合でも、ノード障害の発生時における迅速なリカバリをアプリケーションで提供する必要があります。

ノート:

非同期バックアップをローリング再起動とともに使用するには、stopメソッドまたはkill -9ではなく、shutdownメソッドを使用して、クラスタ・メンバーのシャットダウンを正しい順序で実行する必要があります。そうしないと、非同期バックアップの完了前にメンバーがシャットダウンされる場合があります。shutdownメソッドは、すべての更新が完了することを保証します。

分散キャッシュの非同期バックアップを有効化するには、trueに設定した<async-backup>要素を<distributed-scheme>要素内に追加します。たとえば:

<distributed-scheme>
   ...        
   <async-backup>true</async-backup>
   ...
</distributed-scheme>

分散キャッシュ・サービス・タイプのすべてのインスタンスに対して非同期バックアップを有効にするには、オペレーション・オーバーライド・ファイルで、パーティション・キャッシュ・サービスのasync-backup初期化パラメータをオーバーライドします。たとえば:

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config
   coherence-operational-config.xsd">
   <cluster-config>
      <services>
         <service id="3">
            <init-params>
               <init-param id="27">
                  <param-name>async-backup</param-name>
                  <param-value
                     system-property="coherence.distributed.asyncbackup">
                     false
                  </param-value>
               </init-param>
            </init-params>
         </service>
      </services>
   </cluster-config>
</coherence>

オペレーション・オーバーライド・ファイルを使用するかわりに、coherence.distributed.asyncbackupシステム・プロパティを使用して、分散キャッシュ・サービス・タイプのすべてのインスタンスに対して非同期バックアップを有効にできます。たとえば:

-Dcoherence.distributed.asyncbackup=true

読取りロケータの使用

現在、Coherenceリクエストは、関連付けられたパーティションのプライマリ所有者によって処理されます(クライアント側のキャッシュNearCacheおよびContinuousQueryCacheは無視されます)。Coherence 14.1.1.2206では、読取りロケータ機能が導入されています。読取りロケータを使用すると、特定のリクエストをプライマリ以外のパーティション所有者(バックアップ)にターゲット指定して、リクエストの負荷を分散したり、待機時間を短縮できます。

現在、NamedMap.getおよびNamedMap.getAll (Interface NamedMapを参照)リクエストのみがこの機能をサポートしています。アプリケーションでプライマリ以外のパーティション所有者をターゲット指定することを選択した場合、失効読取りには暗黙的な許容範囲があります。これは、プライマリ(またはその他のバックアップ)が将来/進行中の変更を処理する一方で、読取りを実行したターゲット・メンバーが処理していない場合に発生する可能性があります。

Coherenceでは、次に示すように、キャッシュ構成を使用して、アプリケーションがキャッシュまたはサービスに適切なread-locatorを選択できるようになりました。
...
    <distributed-scheme>
      <scheme-name>example-distributed</scheme-name>
      <service-name>DistributedCache</service-name>
      <backing-map-scheme>
          <read-locator>closest</read-locator>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>
    ...

次のread-locator値がサポートされています。

  • primary - (デフォルト)リクエストをプライマリにのみターゲット指定します。
  • closest - パーティションの所有権チェーン(プライマリおよびバックアップ)のメンバー、マシン、ラックまたは各メンバーのサイト情報に基づいて、最も近い所有者を検索します。
  • random - パーティションの所有権チェーンでランダムに所有者を選択します。
  • random-backup - パーティションの所有権チェーンでランダムにバックアップ所有者を選択します。
  • class-scheme - 所有権チェーンを受け取り、メンバーをターゲットに戻す独自の実装を提供します。

クライアント側のキャッシュNearCacheおよびContinuousQueryCacheの詳細は、ニア・キャッシュの理解および連続問合せキャッシングの使用を参照してください。

バックアップのスケジュール

Coherenceは、アプリケーションが一貫したバックアップ・コピー(async-backup)よりも書込みスループットを優先する機能を提供します。これにより、正常にバックアップされないと、確認済の書込みリクエストが失われる可能性があります。変更メソッドに対して同期APIを使用する場合(put/invoke - Interface ConcurrentMapおよびInterface InvocableMapを参照)、または非同期APIを介して書込みリクエストの完了の通知を受信する場合、確認は返されるコントロールの形式になります。

内部的には、これにより、n書込みリクエストに対してnバックアップ・メッセージが作成され、書込みスループットに直接影響します。書込みスループットを向上されるために、Coherence 14.1.1.2206では、スケジュール済(または定期)バックアップが導入されています。この機能により、バックアップ・メッセージの数を<nにすることができます。

現在のasync-backup XML要素(非同期バックアップの使用を参照)は、単純なtrue|false値よりも多くを受け入れるように拡張され、時間ベースの値をサポートするようになりました。これにより、アプリケーションは、古いバックアップを許容できる期間のソフト・ターゲットを提案できます。実行時に、Coherenceは、バックアップの同期性を加速するか、プライマリ書込みスループットに基づいて失効を増やすかを決定できます。

ノート:

プライマリ・パーティション所有者を失うと更新が失われる可能性があるため、バックアップ間隔を選択する際には注意が必要です。そのプライマリ所有者が送信を待機しているすべての更新は、対応するバックアップ所有者がリストアされてプライマリ所有者になったときに反映されません。

例14-1 構成例

次の分散スキームには、スケジュールされたバックアップ間隔を10秒に設定する例が含まれています。
    ...
    <distributed-scheme>
      <scheme-name>example-distributed</scheme-name>
      <service-name>DistributedCache</service-name>
      <autostart>true</autostart>
      <async-backup>10s</async-backup>
    </distributed-scheme>
    ...
デフォルトのシステム・プロパティを使用することもできます。このプロパティは、使用されるすべての分散スキームに対して有効になります。たとえば:
-Dcoherence.distributed.asyncbackup=10s

非同期永続性の使用

非同期永続性モードでは、記憶域サーバーがデータを非同期に永続化できるため、プライマリがデータを格納し、バックアップが更新を受信すると(同期バックアップがある場合)、変化するリクエストが成功します。

これにより、基礎となるデバイスへの書込み待機時間中に書込みがブロックされないようにすることができますが、書込みが失われる可能性が生じます。このモードは、データを補充できる場合は基本的に使用可能であり、永続化データはデータをリカバリするための最適な手段を提供します。

非同期永続性を有効にするには、<persistence-environment><persistence-mode>active-asyncとして指定します。

このモードを指定する即時利用可能な永続性環境があり、次のいずれかの方法で顧客アプリケーションから参照できます。

  • JVM引数の指定:
    -Dcoherence.distributed.persistence.mode=active-async

    ノート:

    これは、すべての分散サービスで使用されます。
  • キャッシュ構成のdefault-active-async永続性環境の参照:

    「persistence」を参照してください。

    <distributed-scheme>
             ….….….
             <persistence>   
                 <environment>default-active-async</environment>
             </persistence>
             ….….….
    </distributed-scheme>
    

    ノート:

    これにより、永続性が有効になっているサービスを個別に選択できます。

操作構成ファイルで新しい<persistence-environment>要素を定義し、モードにactive-asyncを指定して非同期永続性を有効にすることもできます。「persistence-environment」を参照してください。

たとえば:

<persistence-environment id="async-environment">
         <persistence-mode>active-async</persistence-mode>
         <active-directory>/tmp/store-bdb-active</active-directory>   
         <snapshot-directory>/tmp/store-bdb-snapshot</snapshot-directory>
         <trash-directory>/tmp/store-bdb-trash</trash-directory>
</persistence-environment>

指定された分散スキーマでこの環境を使用するには、この環境をキャッシュ構成で参照する必要があります。

たとえば:

<distributed-scheme>
         ….….….
         <persistence>   
             <environment>async-environment</environment>
         </persistence>
         ….….….
</distributed-scheme>

ノート:

非同期永続性では、永続トランザクションが完了する前にクラスタが停止されると、データが失われる可能性があります。

管理された停止中にデータ損失がないようにするために、顧客はサービス中断機能を利用することができます。サービスは、すべてのデータが完全に書き込まれた後でのみ中断とみなされます(非同期永続性タスク、読取り/書込みバッキング・マップのライトビハインド・キューのエントリを含む)。

永続バックアップの使用

Coherence 14.1.1.2206では、永続化されたプライマリ・パーティションの追加コピーとしてバックアップ・パーティションをディスクに格納する新しい永続性モードが追加されています。

この項には次のトピックが含まれます:

永続バックアップについて

アクティブ永続性モードでは、Coherenceはプライマリ・パーティションをディスクに徹底的に永続化して、完全な停止(自発的または自発的でない)が発生した場合にデータのリカバリを許可します。

このモードでは、実行時に、すべてのキャッシュ変更が同期的にディスクに保存されます。つまり、クライアントに制御を戻す前にキャッシュ更新が完了するのを待機するすべての操作は、永続性の完了も待機します。

アクティブ永続性によって信頼性が向上しますが、データが失われる可能性のある状況は残ります。たとえば、メンバーが同じ場所に保存していない場合や、一部の場所がアクセス不可になっていたり破損している場合です。

この問題を軽減するために、新しいモード"active-backup"でもバックアップ・パーティションがディスクに保持されます。この操作は、パフォーマンスにできるだけ影響を与えないように、常に非同期です。

このモードでは、リカバリ中にプライマリ・パーティションが見つからない場合、バックアップ・パーティションが検索され、かわりに使用されます。最も単純なのは、記憶域が有効な2つのメンバーが2つの異なるマシンで実行されており、それぞれに独自の記憶域があるクラスタの場合です。このトポロジでは、それぞれがプライマリ・パーティションとバックアップ・パーティションにほぼ均等に分割されます。メンバー1は、プライマリ・パーティションP1、P2およびP3と、バックアップ・パーティションB4、B5、B6およびB7を所有します。メンバー2は、P4、P5、P6およびP7と、B1、B2およびB3を所有します。

両方のメンバーが失われ、1つの記憶域しかリカバリできない場合、1つの残っている記憶域を使用することで任意のメンバーを再起動し、データのセット全体をリカバリできます。アクティブ(非バックアップ)モードでは、同じ状況でデータ・セットの約半分しかリカバリされません。

アクティブ永続性モードの構成

このモードは、coherence.distributed.persistence.modeの永続性モード"active-backup"値を使用して構成できます。たとえば:
-Dcoherence.distributed.persistence.mode=active-backup

オプションで、Coherence操作オーバーライド・ファイルの<backup-directory/>を使用してバックアップ・パーティションを格納するようにバックアップの場所を構成できます。それ以外の場合は、 coherence.distributed.persistence.base.dir (またはそのデフォルト)の後に'/backup'が続くパスに格納されます。

たとえば:
<persistence-environments>
   <persistence-environment id="active-backup-environment">
     <persistence-mode system-property="coherence.persistence.mode">active-backup</persistence-mode>
       <active-directory system-property="coherence.persistence.active.dir">/store-bdb-active</active-directory>
       <backup-directory system-property="coherence.persistence.backup.dir">/store-bdb-backup</backup-directory>
       <snapshot-directory system-property="coherence.persistence.snapshot.dir">/store-bdb-snapshot</snapshot-directory>
       <trash-directory system-property="coherence.persistence.trash.dir">/store-bdb-trash</trash-directory>
   </persistence-environment>
</persistence-environments>

パフォーマンスに関する考慮事項

実行時のパフォーマンスへの影響は最小限ですが、考慮すべきパフォーマンス上の考慮事項があります。作成される永続性ファイルが多いため、特に構成されるパーティションの数が多い場合、起動時間とリカバリ時間に影響する可能性があります。起動/リカバリ時間への影響を最小限に抑えるために、リカバリ・クォーラムを使用できます。

例: キャッシュ構成の場合:
<distributed-scheme>
    <scheme-name>partitioned</scheme-name>
    <backing-map-scheme>
        <partitioned>true</partitioned>
        <read-write-backing-map-scheme>
            <internal-cache-scheme>
                <local-scheme>
                </local-scheme>
            </internal-cache-scheme>
        </read-write-backing-map-scheme>
    </backing-map-scheme>
    <partitioned-quorum-policy-scheme>
       <recover-quorum>3</recover-quorum>
    </partitioned-quorum-policy-scheme>
    <autostart>true</autostart>
</distributed-scheme>

前述の例では、recover-quorumの値をクラスタ内の必要なメンバー数に設定できます。これにより、その数のメンバーが参加している場合にのみリカバリが発生します。分散と同時にリカバリが実行されるのではなく、リカバリは1回のみ実行され、より速く完了します。

デルタ・バックアップの使用

デルタ・バックアップとは、プライマリ・エントリが変更されたときに、エントリ全体を置き換えるのではなく、バックアップ・バイナリ・エントリに変更を適用するために使用される技術です。デルタ・バックアップは、更新しようとするエントリが大きいにもかかわらず変更が小さい場合に最適です。そのような場合、エントリ全体の書換えに関するコストよりエントリの一部分のみを変更するコストの方が一般的には小さいので、パフォーマンスが向上します。ただし、一般的に、エントリに50%を超える変更があると、パフォーマンスの向上はほとんどまたはまったくありません。この場合、パフォーマンスの低下が検出されないときにのみデルタ・バックアップを使用してください。

デルタ・バックアップでは、新旧の値を持つ2つのインメモリー・バッファを比較するコンプレッサを使用し、古い値に適用して新しい値を作成できる結果(デルタといいます)を生成します。Coherenceでは、POFおよび非POF形式の標準のデルタ・コンプレッサを備えています。必要に応じて、カスタム・コンプレッサを作成することもできます。

この項には次のトピックが含まれます:

デルタ・バックアップの有効化

デルタ・バックアップは分散キャッシュでのみ使用可能で、デフォルトでは無効です。デルタ・バックアップは、それぞれの分散キャッシュで個別に有効にするか、分散キャッシュ・サービス・タイプのすべてのインスタンスに有効にします。

分散キャッシュでデルタ・バックアップを有効にするには、<compressor>要素を<distributed-scheme>要素の中に追加して、standardに設定します。たとえば:

<distributed-scheme>
   ...        
   <compressor>standard</compressor>
   ...
</distributed-scheme>

分散キャッシュ・サービス・タイプのすべてのインスタンスにデルタ・バックアップを有効にするには、オペレーション・オーバーライド・ファイルで、パーティション・キャッシュ・サービスのcompressor初期化パラメータをオーバーライドします。たとえば:

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config
   coherence-operational-config.xsd">
   <cluster-config>
      <services>
         <service id="3">
            <init-params>
               <init-param id="22">
                  <param-name>compressor</param-name>
                  <param-value
                     system-property="coherence.distributed.compressor">
                     standard</param-value>
               </init-param>
            </init-params>
         </service>
      </services>
   </cluster-config>
</coherence>

オペレーション・オーバーライド・ファイルを使用するかわりに、coherence.distributed.compressorシステム・プロパティを使用して、分散キャッシュ・サービス・タイプのすべてのインスタンスに対してデルタ・バックアップを有効にできます。たとえば:

-Dcoherence.distributed.compressor=standard

カスタム・デルタ・バックアップ・コンプレッサの有効化

カスタム・コンプレッサを使用してデルタ・バックアップを実行するには、<instance>サブ要素を追加して、DeltaCompressorインタフェースを実装するクラスの完全修飾名を指定します。instanceを参照してください。次の例では、MyDeltaCompressorクラスに実装されているカスタム・コンプレッサが有効になります。

<distributed-scheme>
   ...        
   <compressor>
      <instance>
         <class-name>package.MyDeltaCompressor</class-name>
      </instance>
   </compressor>
   ...
</distributed-scheme>

代替案として、<instance>要素では、DeltaCompressorインスタンスを作成するためのファクトリ・クラスを使用する<class-factory-name>要素、およびオブジェクトのインスタンス化を実行するファクトリ・クラス上で静的なファクトリ・メソッドを指定する<method-name>要素の使用がサポートされています。次の例では、MyCompressorFactoryクラスのgetCompressorメソッドを使用するカスタム・コンプレッサ・インスタンスを取得します。

<distributed-scheme>
   ...        
   <compressor>
      <instance>
         <class-factory-name>package.MyCompressorFactory</class-factory-name>
         <method-name>getCompressor</method-name>
      </instance>
   </compressor>
   ...
</distributed-scheme>

実装に必要な初期化パラメータはすべて、<init-params>要素を使用して指定できます。次の例では、iMaxTimeパラメータが2000に設定されます。

<distributed-scheme>
   ...        
   <compressor>
      <instance>
         <class-name>package.MyDeltaCompressor</class-name>
         <init-params>
            <init-param>
               <param-name>iMaxTime</param-name>
               <param-value>2000</param-value>
            </init-param>
         </init-params>
      </instance>
   </compressor>
   ...
</distributed-scheme>

Caffeineの統合

Coherence 14.1.1.2206では、Caffeineバッキング・マップ実装が追加され、標準のCoherenceローカル・キャッシュを使用できる場所(ローカル・キャッシュとして、パーティション・キャッシュのバッキング・マップとして、またはニア・キャッシュのフロント・マップとして使用)でCaffeineを使用できます。

この項には次のトピックが含まれます:

Caffeineについて

Caffeineは、パフォーマンスが高く、ほぼ最適なキャッシュ・ライブラリです。読取りおよび書込みの同時実行性の向上とヒット率の向上により、Coherenceの標準ローカル・キャッシュが改善されます。

Caffeineは、多種多様なワークロードで大幅に高いヒット率を達成できる適応型のエビクション・ポリシーを実装しています。この機能を利用すると、待機時間を短縮したり、より小さいキャッシュで同じパフォーマンスを維持できます。これにより、同じワークロードに必要なリソースが少なくなるため、運用コストを削減できます。詳細は、Caffeineを参照してください

W-TinyLFUというニックネームが付いたこのポリシーの適応性により、実行時のワークロードが変化しても、堅牢なパフォーマンスを維持できます。詳細は、Adaptive Software Cache ManagementおよびTinyLFU: A Highly Efficient Cache Admission Policyを参照してください。これらの変更は、外部リクエスト・パターンのバリエーション、またはアプリケーションの進化による差異によって発生する可能性があります。この自己最適化のO(1)アルゴリズムにより、アプリケーションを手動で分析し、キャッシュをより最適なエビクション・ポリシーにチューニングする必要がなくなります。

次の表に、様々なタイプのワークロードについて、一般的に使用される他のキャッシュ・エビクション・ポリシーと比較した、CaffeineのW-TinyLFUのキャッシュ・ヒット率を示します。

表14-1 CaffeineのW-TinyLFUと一般的な他のキャッシュ・エビクション・ポリシーのキャッシュ・ヒット率

ワークロード W-TinyLFU ハイブリッド LRU LFU

分析ループ

32.7%

2.6%

1.0%

1.4%

ブロックチェーンのマイニング

32.3%

12.1%

33.3%

0.0%

OLTP

40.2%

15.4%

33.2%

9.6%

検索

42.5%

31.3%

12.0%

29.3%

データベース

44.8%

37.0%

20.2%

39.1%

Caffeineの詳細な紹介については、次の記事を参照することを強くお薦めします。

Caffeineの使用

CaffeineはCoherenceに緊密に統合されており、Coherenceが提供する組込みバッキング・マップ実装とほぼ同様に使いやすくなっています。唯一の違いは、CaffeineはCoherence POM内のオプションの依存関係として定義されているため、CaffeineではプロジェクトのPOMファイルにCaffeineへの依存関係を追加する必要があることです。

Caffeineを使用できるようにするには、POMファイルに次の依存関係を追加する必要があります。
<dependency>
  <groupId>com.github.ben-manes.caffeine</groupId>
  <artifactId>caffeine</artifactId>
  <version>${caffeine.version}</version>
</dependency>

サポートされているCaffeineバージョンは、3.1.0以上です。

Caffeineの構成

依存関係を追加すると、Caffeineは標準のローカル・キャッシュ実装と同じように簡単に使用できます。

Coherenceには、local-scheme要素が現在使用されている任意の場所(スタンドアロン、ローカル・キャッシュ・スキームの定義、パーティション・キャッシュのbacking-mapとしてのdistributed-scheme要素内、またはfront-mapとしてのnear-scheme要素内)で使用できるcaffeine-scheme構成要素が用意されています。

ローカル・キャッシュ
<caffeine-scheme>
   <scheme-name>caffeine-local-scheme</scheme-name>
</caffeine-scheme>
分散キャッシュ
<distributed-scheme>
    <scheme-name>caffeine-distributed-scheme</scheme-name>
    <backing-map-scheme>
        <caffeine-scheme />
    </backing-map-scheme>
    <autostart>true</autostart>
</distributed-scheme>
ニア・キャッシュ
<near-scheme>
    <scheme-name>caffeine-near-scheme</scheme-name>
    <front-scheme>
        <caffeine-scheme />
    </front-scheme>
    <back-scheme>
        <distributed-scheme>
            <scheme-ref>my-dist-scheme</scheme-ref>
        </distributed-scheme>
    </back-scheme>
</near-scheme>

次の1つ以上の子要素を指定することで、local-schemeの構成と同じ方法で各caffeine-scheme要素を構成できます。

表14-2 caffeine-scheme要素内の子要素

構成要素 説明

scheme-name

このスキームの名前。構成ファイル内の別の場所から参照できます。

scheme-ref

構成ファイルの他の場所で定義されているcaffeine-schemeへの参照(名前による)。

class-name

com.oracle.coherence.caffeine.CaffeineCacheを拡張するカスタム・クラスの名前で、その動作をカスタマイズできます。

scope-name

スコープの名前。

service-name

サービスの名前。

init-params

class-nameコンストラクタに渡す引数。

high-units

エビクションが発生する前にキャッシュが保持できるデータの最大量。

unit-calculator

使用する単位換算カリキュレータ。通常は次のいずれかです。
  • BINARYは、シリアライズされた形式のキャッシュ・キーと値が消費するバイト数に基づいて「ユニット」の数を決定します。
  • FIXEDは、単にエントリ数を「ユニット」として使用します。

unit-factor

BINARYカリキュレータと組み合せて使用することで、「ユニット」の2GB制限を克服する場合もあります。たとえば、1024を「ユニット・ファクタ」として指定すると、high-unitsをバイト単位ではなくキロバイト単位で表すことができます。

expiry-delay

前回の更新からエントリが破棄されるまでの、エントリがキャッシュに保持される期間。

listener

キャッシュに登録するMapListener

前述のすべての構成要素はオプションですが、通常はhigh-unitsまたはexpiry-delay (あるいはその両方)を設定して、サイズまたは存続時間(TTL)のいずれかに基づいてキャッシュを制限します。

どちらも指定しない場合、キャッシュ・サイズは使用可能なメモリーによってのみ制限され、NamedCache.put(key, value, TTL)メソッドを使用するか、エントリ・プロセッサ内でBinaryEntry.expireをコールすることで、TTLを明示的に指定できます。

サイズまたは時間によってキャッシュを制限したくない場合は、何も問題はありません。ロックフリーの実装が原因で、特に同時負荷が高い状況では、Caffeineを使用することでメリットが得られる場合があります。

最後に、パーティション・キャッシュのバッキング・マップとしてCaffeineを使用する場合は、unit-calculatorBINARYに構成することをお薦めします。これにより、キャッシュ内のエントリ数ではなくバイト単位で制限を設定し、(JMXまたはメトリックを介して)キャッシュ・サイズを監視できます。