この章では、バッキング・マップを使用したCoherenceの記憶域について説明します。この章の内容は次のとおりです。
Coherenceのパーティション(分散)キャッシュ・サービスは、次の3つのレイヤーに分かれています。
クライアント・ビュー: 基礎となるパーティション化されたデータへのアクセスを可能にする仮想レイヤー。この層へのアクセスには、NamedCacheインタフェースが使用されます。このレイヤーでは、NearCacheやContinuousQueryCacheなどの統合データ構造も作成できます。
ストレージ・マネージャ: クライアント層からのキャッシュ関連リクエストを処理するサーバー側の層です。実際のキャッシュ・データ(プライマリ・コピーおよびバックアップ・コピー)、およびロック、イベント・リスナー、マップ・トリガーなどに関する情報を格納するデータ構造を管理します。
バッキング・マップ: 実際のデータを格納するサーバー側のデータ構造。
Coherenceでは、出荷状態のまま使用できるバッキング・マップ実装に加えて、カスタム実装を構成できます。基本的に、これらすべてのマップ実装における唯一の制約は、ストレージ・マネージャではキーと値がすべて内部(バイナリ)形式で指定されるということであり、その点に留意する必要があります。内部データとオブジェクト形式との間の変換を処理するため、ストレージ・マネージャでは、BackingMapManagerContext参照によるバッキング・マップの実装が可能です。
図14-1はバッキング・マップの概念図です。
バッキング・マップに対して実行される操作にはいくつかのタイプがあります。
アプリケーションの使用によって必然的に発生するアクセスおよび更新操作。たとえば、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()操作によって発生する挿入操作(リードスルー機能またはリードアヘッド機能が構成されたバッキング・マップの場合)
パーティション分散によって発生する統合アクセスおよび更新(パーティション分散はクラスタ・ノードのフェイルオーバーまたはフェイルバックから発生する場合があります)。この場合は、アプリケーション層のコールがなくても、バッキング・マップの多数のエントリが挿入または削除されることがあります。
バッキング・マップでは、実際の実装方法に応じて次のいずれかの方法でキャッシュ・データが格納されます。
ヒープ上メモリー
ヒープ外メモリー
ディスク(メモリーマップ・ファイルまたはインプロセスDB)
上述のいずれかの組合せ
データをメモリーに格納することで、アクセスおよび更新の待機時間が大幅に短縮されます。また、これは最も一般的に使用される方法でもあります。
たいていの場合、アプリケーションでは、データ・グリッドに配置されるデータの合計量が事前設定されたメモリー量を超えないようにする必要があります。これは、アプリケーション層ロジックによって直接制御することも、サイズ・ベースまたは有効期限ベースのエビクションによって自動的に制御することもできます。その結果、当然のことながら、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の容量制限があります。このバッキング・マップで保持されるデータの合計量が高水位標を超えると、バッキング・マップから一部のエントリが削除され、データの量が低水位標値(<low-units>構成要素、デフォルトでは<high-units>の75%)まで減少します。削除されるエントリの選択方法は、LRU(最低使用頻度)エビクション・ポリシーに従います。その他のオプションには、LFU(最低アクセス頻度)および混合(LRUとLFUの組合せ)があります。<high-units>の値は2GBに制限されます。この制限を解除するため(ただし下位互換性は保持)、Coherenceでは<unit-factor>要素が使用されます。たとえば、<high-units>値が8192で<unit-factor>が1048576の場合、高水位標値は8GBになります(次の構成抜粋を参照してください)。
<backing-map-scheme>
  <local-scheme>
    <expiry-delay>1h</expiry-delay>
  </local-scheme>
</backing-map-scheme>
このバッキング・マップは、未更新の状態のまま1時間を超えたエントリを自動的に削除します。ただし、これは緩慢な削除方法であり、最終更新から1時間以上経過したエントリが削除されますが、必ずしも1時間経過後ただちに削除されるわけではありません。この場合保証されるのは、1時間以上超過したエントリがコール元に返されないことのみです。
<backing-map-scheme>
  <external-scheme>
    <nio-memory-manager>
      <initial-size>1MB</initial-size>
      <maximum-size>100MB</maximum-size>
    </nio-memory-manager>
    <high-units>100</high-units>
    <unit-calculator>BINARY</unit-calculator>
    <unit-factor>1048576</unit-factor>
  </external-scheme>
</backing-map-scheme>
このバッキング・マップは、com.tangosol.net.cache.SerializationCacheのインスタンスであり、拡張(NIO)メモリーに値を格納しますが、100MB(100*1048576)の容量制限があります。当然ながら、このキャッシュのバックアップ記憶域はoff-heap(またはfile-mapped)として構成します。
<backup-storage> <type>off-heap</type> <initial-size>1MB</initial-size> <maximum-size>100MB</maximum-size> </backup-storage>
従来のバッキング・マップの実装には、対応するノードが所有するすべてのパーティションのエントリが含まれていました(パーティション送信時に、クライアントから見て一時的に所有者の存在しない「未完了」エントリも保持されることがありました)。
図14-2は従来のバッキング・マップ実装の概念図です。
パーティション・バッキング・マップは、基本的には、実際のマップ実装の多重化であり、それぞれのマップには同じパーティションに属するエントリのみが格納されます。
図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>
    <unit-factor>1048576</unit-factor>
  </external-scheme>
</backing-map-scheme>
このバッキング・マップはcom.tangosol.net.partition.PartitionSplittingBackingMapのインスタンスであり、マップを保持する個別のパーティションであるcom.tangosol.net.cache.SerializationCacheのインスタンスから構成され、各パーティションの拡張(nio)メモリーに値が格納されます。nioバッファにはそれぞれ50MBの制限がありますが、バッキング・マップ全体の容量制限は8GB(8192*1048576)です。この場合も、このキャッシュのバックアップ記憶域はoff-heapまたはfile-mappedとして構成する必要があります。