200
Java EE7 JCache @maruyama097 丸山不二夫

Java EE7 䛸㻌JCache

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Java EE7 䛸㻌JCache

Java EE7 と JCache

@maruyama097 丸山不二夫

Page 2: Java EE7 䛸㻌JCache

はじめに

o  筆者の基本的な問題意識は、ネットワーク上のマーケットが急速に拡大するという展望の中で、エンタープライズ・システムを、もっと高速でスケーラブルなものにしつつ、トランザクションの正確性をきちんと担保することである。

o  そこでは、キャッシュ技術は欠かせない。 事実、分散キャッシュについては、多くの商業製品、オープンソースのプロジェクトが登場し利用されている。にもかかわらず、エンタープライズJavaの標準的なキャッシュ技術というべきものは、存在しなかった。

o  その点で、Java EE7の仕様の一つとして、エンタープライズJavaの標準的なキャッシュ技術となるべく検討されている、JCacheに、注目している。

Page 3: Java EE7 䛸㻌JCache

はじめに

o  プレゼンの前半で、同じキャッシュというくくりで、CPUとメモリーの間に置かれている、キャッシュの問題についてCliff Clickの議論の紹介をした。もっとも、これは、キャッシュが有効に機能していないという例なのだが。

o  また、CPUのMulti-core化が、キャッシュにとってどういう意味を持つかを考えてみた。意外と複雑で、残念ながら、すっきりした見通しは持てなかった。

o  現在のJCacheの仕様には、分散キャッシュの実装、あるいは、そのインターフェースの利用について、明示的な言及は無い。昨年、立ち上がった、JSR 347: Data Grids for the JavaTM Platform が、その一つの答えだと思うのだが、今後の進展を注目している。

Page 4: Java EE7 䛸㻌JCache

Agenda

o  CPUとキャッシュ o  Multi-Core CPUとメモリー o  システムの階層性とキャッシュ o  WebアプリのScale-outと

分散メモリーキャッシュ、NoSQL o  JSR 347: Data Grids for the JavaTM

Platform o  JSR 107: JCACHE - Java Temporary

Caching API

Page 5: Java EE7 䛸㻌JCache

CPUとキャッシュ

Not Your Father's Von Neumann Machine:A Crash Course in Modern Hardware Cliff Click Azul Systems Brian Goetz Sun Microsystems http://www.azulsystems.com/events/javaone_2009/session/2009_J1_HardwareCrashCourse.pdf から

Page 6: Java EE7 䛸㻌JCache

CPU Performance

Multicore era

Frequency scaling era

CISC era

Page 7: Java EE7 䛸㻌JCache

CPUとメモリーのスピードのギャップ

o  CPUとメモリーのスピードのギャップは拡大している。かつてのCPUのメモリーアクセスは、レジスターのフェッチよりほんの少し遅いだけだった。今日では、メイン・メモリーからのデータの取り込みは数百クロック・サイクルを要する。 http://t.co/PekDYDFf

Page 8: Java EE7 䛸㻌JCache

CPUのキャッシュ

o  かつては、乗算は高価な処理で、メモリーからのLoadは安価な処理だった。しかし、今では、乗算は安価な処理で、メモリーからのLoadは、高価な処理である。

o  CPUとメモリーのスピードのギャップが広がる中で、今日のCPUは、洗練された多段のキャッシュを発展させてきた。ただ、CPUのパフォーマンスに、決定的な影響を与えるのは、CPUの実行スピードではなく、キャッシュ・ミスなのである。

o  Static RAMは、高速だが高価である。Dynamic RAMは、安価だが低速である。CPUのキャッシュとは、高速のSRAMをCPUの近くに配置して、メモリーのパフォーマンスを良くしようと言うもの。

Page 9: Java EE7 䛸㻌JCache

コードとデータの局所性

o  キャッシュが効くのは、多くのプログラムのコードもデータも「局所性」を持つから。コードとデータは、それぞれ固有の「局所性」を持つので、コードのキャッシュとデータのキャッシュの両方が必要である。

Page 10: Java EE7 䛸㻌JCache

データをCPUの近くに置く

o  「データをCPUの近くに置くこと!」 メモリー遅延の最大の要因は、伝送線の遅延である。ここでは、情報伝達の上限である光のスピードが問題になる。1GHzのCPUの1クロックの間に、信号は、光のスピードでも、30cm以上を進むことが出来ない。

o  CPU-メモリーのスピードギャップが広がるにつれ、多段のキャッシュが必要になってきた。ただレジスタへのアクセスが、1クロック以下で可能なのに対して、L1キャッシュは3clk、L2キャッシュは15clk、メモリーアクセスには200clk必要 http://t.co/pmEqEmt9

Page 11: Java EE7 䛸㻌JCache

メモリーは、新しいディスク

o  キャッシュミスの確率は、現在ではかなり低い。ただ、キャッシュミスによって、100〜1000命令分の時間のコストが発生する。だから、キャッシュミスの確率が5%前後だとしても、パフォーマンスに対するインパクトは、キャッシュミスの方が大きなものになる。

o  CPUとメモリーのスピードのギャップが拡大するにつれて、キャッシュミスがCPUのパフォーマンスを決めるといってもいいのだ。「いまや、メモリーは、新しいディスクなのだ。」

Page 12: Java EE7 䛸㻌JCache

Multi-coreとキャッシュ

o  Multi-coreのシステムでは、最下層のキャッシュは、いくつかのコアで共有されている。

o  しかし、全てのキャッシュが、全てのコアから見える訳ではない。

Page 13: Java EE7 䛸㻌JCache

Multi-Core CPUとメモリー

Page 14: Java EE7 䛸㻌JCache

http://www.socip.org/socip/speech/pdf/20110708-080436-Perfectvips-SoCIP%202011%20Presentation.pdf

わずか10年の間のトランジスタ数の変化

Page 15: Java EE7 䛸㻌JCache
Page 16: Java EE7 䛸㻌JCache

Multi-Coreのコア数とトランジスター数

コア数 トランジスター数 CPU

2 300M Apple A5

10 2600M Westmere EX

48 1300M SCC

100 500M Tile GX 100

Page 17: Java EE7 䛸㻌JCache

Multi-Coreのコア数と外部メモリー

o  コアの数が増えても、そのチップからアクセス可能なメモリーの量は、コアの数に比例して増えていく訳ではない。‎100コアのTilera TileGX100が、10コアのWestMere-EXの、10倍のメモリー空間を持つ訳ではない。

o  Multi-Coreチップの外部メモリーの量は、コアの数ではなく、そのチップが何個のメモリー・コントローラを持っているかで上限が決まっている。4個のメモリーコントロラーをもつSCCのメモリーは、4x16の64G「しか」ない。

o  そこは、コモディティ化したノードをメモリー、ディスクごと増やしていく、これまでのスケールアウト・アーキテクチャーのメモリーの計算の仕方とは、異なる。

Page 18: Java EE7 䛸㻌JCache

SCCのメモリー構造

共有外部メモリー(可変長)

コア毎の 外部メモリ (可変長)

L1 Cache 16K

cpu_0 L2

Cache 256K

コア毎の 外部メモリ (可変長)

L1 Cache 16K

cpu_47 L2

Cache 256K

チップ上の共有メッセージ・パッシング・バッファー 384K 8K/core

Page 19: Java EE7 䛸㻌JCache

SCCの共有仮想メモリー空間

o  コアをまたいだ、共有仮想空間が利用できる。

o  アプリケーションから見ると、単一のメモリー空間に見える。

o  複数のcore間で、シームレスにデータ構造やポインターを共有できる。

共有 仮想メモリー

アプリケーション

基本的に、Parallel型の利用法

Page 20: Java EE7 䛸㻌JCache

SCCの物理アドレス

o  SCCのそれぞれのコアは、32ビット(4GB)のアドレス空間を持っている。

o  通常は、物理アドレスは、FSB(Front Side Bus)上に見える。

o  SCCでは、物理アドレスは、十分ではない。64GBのメモリーと、無数のSCCシステム・アドレス(12bit+34bit)がある。

o  物理アドレスをSCCシステム・アドレスに変える変換器が必要である。

Page 21: Java EE7 䛸㻌JCache
Page 22: Java EE7 䛸㻌JCache

48コアが、4つのメモリーコント ローラを持つ。デフォールトでは 12コアに一つのコントローラが 割り当てられている。

Page 23: Java EE7 䛸㻌JCache

In-Memory Communication Mechanisms for Many-Cores - Experiences with the Inte SCC

http://communities.intel.com/docs/DOC-19423

Page 24: Java EE7 䛸㻌JCache
Page 25: Java EE7 䛸㻌JCache
Page 26: Java EE7 䛸㻌JCache

Efficient Memory Copy Operations on the 48-core Intel SCC Processor

http://dare.uva.nl/document/356252

Page 27: Java EE7 䛸㻌JCache

システムの階層性とキャッシュ

Page 28: Java EE7 䛸㻌JCache

処理スピードで規定される階層性

o  システムの階層性を規定しているのは、処理のスピードである。次のような階層がある。 CPU > メモリー > ディスク > ネットワーク

o  キャッシュは、基本的には、階層間をつなぐ働きをする。 n  CPU/メモリー: L1,L2キャッシュ n  メモリー/ディスク: nio、mmap。ディスクのメモリー・キャッシュ。

SSD。 n  メモリー/ネットワーク: ... n  ディスク/ネットワーク: ...

Page 29: Java EE7 䛸㻌JCache

メモリーのコストの階層性

o  処理スピードの階層性の他に、コストの階層性がある。基本的には、処理スピードの階層性を裏打ちしているようにも見えるが、本来は、別の原理である。 SRAM > DRAM > SSD > Disk

o  SRAMのように高速で、DRAMのように安価なメモリーが登場すれば、アーキテクチャは、大きく変わりうる。

Page 30: Java EE7 䛸㻌JCache

ネットワークのスピードとコスト

o  こうした処理スピードとコストの階層性は、固定的なものでは無い。ネットワークの処理スピードは向上し、コストは低下しうる。もし、次のようになったら? CPU = ネットワーク > メモリー > ディスク

o  Gilderは、かつて、次のように述べていた。 ネットワークがコンピュータの内部バスと同じぐらい早くなれば、マシンは、特定の目的を持ったデバイスのあつまりへとネットワーク上で分解するだろう。

Page 31: Java EE7 䛸㻌JCache

Hard Disk

http://www2s.biglobe.ne.jp/~sakharov/index.html

ディスクの価格低下のインパクト

半導体のMoore則

ディスクの価格低下

ディスク1G 5円

Page 32: Java EE7 䛸㻌JCache

ACM 2012 The Future of Microprocessors

o  プロセッサのパフォーマンスの新しい基本的な制限が、エネルギー効率だと言う視点からの分析。

o  今日のプロセッサのパフォーマンスは、毎秒100Giga-opのオーダーである。パフォーマンスは、次の10年で30倍になり、毎秒3Tera-opに達するであろう。

o  少なく見積もっても、この時、9T-オペランド、すなわち64b × 9T-オペランド (576T-bits!) が、毎秒、レジスター/メモリーから演算器等に移動するのだが、それはエネルギーを消費する。

http://delivery.acm.org/10.1145/1950000/1941507/p67-borkar.pdf

Page 33: Java EE7 䛸㻌JCache

o  もしもオペランドが平均して1mm (ダイサイズの10%)移動するとして、0.1pJ/bitの割合だとすると、576T-bitsの移動は、約58ワットを消費することになり、計算に必要なエネルギーは、ほとんど残っていない。

o  Many-coreシステムのコアは、コアとコアの間を、チッ

プ上のネットワークを通じてデータが移動する。 o  オペランドの10%がネットワーク上に流れ、平均10ホッ

プで移動するとして、0.06pJ/bit としてネットワークの電力消費は、35ワットになり、プロセッサーに割り当てられている電力の半分以上を消費することになる。

Page 34: Java EE7 䛸㻌JCache

WebアプリのScale-outと 分散メモリーキャッシュ、NoSQL

Page 35: Java EE7 䛸㻌JCache

Web Appli Multi-tier のScale-out戦略

Web Server  Business Logic Daa Base

Page 36: Java EE7 䛸㻌JCache

・・・・・・・

Web Appli Multi-tier のScale-out戦略

Load Balancer

Web Server Business Logic

Daa Base

Page 37: Java EE7 䛸㻌JCache

・・・・・・・

Web Appli Multi-tier のBottle Neck

Load Balancer

Web Server Business Logic

Daa Base

Page 38: Java EE7 䛸㻌JCache

Multi-tier の分散メモリーCache

・・・・・・・

Load Balancer

Web Server Business Logic

Daa Base

Page 39: Java EE7 䛸㻌JCache

Cloud上の分散データベース

On Memory Hash

Persistency

Page 40: Java EE7 䛸㻌JCache

分散キャッシュのプロダクト

o  市場には、多くの分散キャッシュのプロダクトが、存在している。

o  代表的なものをあげれば、 OracleのCoherence (Cameron Purdy)、 IBMのeXtreme Scale (Billy Newport)、 TerracottaのEhCache (Greg Luck)、 MicrosoftのAppFabric。

o  もちろん、低レーヤでは、オープンソースのmemcachedが広く利用されている。日本発のキャッシュ技術も、優れたものがある。

n  個人的には、JSR107のEGに、Cameron Purdy、Billy

Newport、Greg Luckの三人が入っているのに、期待している。

Page 41: Java EE7 䛸㻌JCache

キャッシュとNoSQLの比較

o  キャッシュは、Key/Value。 NoSQLのあるものは、Key/Value。

o  キャッシュの主目的は、パフォーマンス。 NoSQLの主目的は、永続性。

o  キャッシュは、永続性を持ちうる。 NoSQLは、常に永続性を持つ。

o  永続するキャッシュは、NoSQLのユースケースの一部をカバーする。NoSQLのあるものは、キャッシュのユースケースをカバーする。

Page 42: Java EE7 䛸㻌JCache

キャッシュとNoSQLの比較

o  キャッシュのサイズは小さい。〜数十GB NoSQLのサイズは、数TB〜数PB

o  キャッシュはメモリーに置かれる。 NoSQL、RDBMSは、ディスクに置かれる。

o  キャッシュは、メモリー上のデータストア。 NoSQLは、Relation無しのDBMS。

Page 43: Java EE7 䛸㻌JCache

JSR 347: Data Grids for the JavaTM Platform

Page 44: Java EE7 䛸㻌JCache

Description

o  この仕様は、分散データグリッドに、アクセスし、格納し、データを管理するAPIを提供することを目的としたものである。

o  最初のAPIは、JSR-107 (JCACHE) APIの上に、その拡張として構築されるだろう。JSR-107は、キャッシュにアクセスする一般化されたMAPに似たAPIに加えて、イン・メモリーのデータをパーシステントなストレージにスプールするSPI、CacheManagerから名前のついたCacheを取得するAPI、イベント・リスナーを登録するAPIを定義している。

Page 45: Java EE7 䛸㻌JCache

o  JSR-107の上にそれを超えて、このJSRは、権限の引き渡し、複製化、分散、トランザクション(JTAの仕様に基づいて)の特徴と期待される特質を定義するだろう。

o  さらに、非同期で、ノンブロッキングなAPIを、JSR-107の最初のAPIに変わるものとして定義するだろう。というのも、データに対するノンブロッキング・アクセスは、データグリッドのように、リモート呼び出しを実行する必要のある実装では、関心事になるからである。

Page 46: Java EE7 䛸㻌JCache

o  この仕様は、まだ完成していないJSR-107の上に構築される。我々は、彼らのスケジュールが、このJSRのスケジュールと両立出来ることを保証する為に、JSR-107のEGと、ともに作業する意向である。もし、JSR-107が完成することが出来なければ、最後の利用可能なドラフトを、この仕様にマージすることを提案する。

Page 47: Java EE7 䛸㻌JCache

Proposed features

o Async API (Future based) public interface AsyncCache<K, V> {

Future<V> get(K key); Future<Void> put(K key); Future<V> getAndPut(K key); Future<Boolean> remove(K key); Future<V> getAndRemove(K key); ... etc ... }

Page 48: Java EE7 䛸㻌JCache

Proposed features o Distributed code execution

n  Map/Reduce n  Alternate proposal

o Group API o CDI (Contexts and Dependency

Injection) integration o  Transactions (JTA) integration o Operation Mode o  Eventually Consistent API

Page 49: Java EE7 䛸㻌JCache

Proposed features

o Configuration o Drop-In Replacement for JSR-107

Compliant Caches

Page 50: Java EE7 䛸㻌JCache

JSR-347 Spec Lead Manik Surtani氏とのインタビュー

o  JSR 347はJavaプラットフォーム向けのデータグリッドとしても知られていますが、APIとプログラミングモデル、そしてフォルトトレラントなインメモリの分散キーバリューストアの振る舞いについて標準化するために提案されたものです。JSR 107 (Javaプラットフォーム向け一時キャッシュ)との違いはたくさんあります。

o  データの永続性。JSR 347はレコードの保存機構であり、本質的な分散の仕組みによって耐久性を提供します。一方、JSR 107は一時的で揮発性の高いデータを保存する前提の仕様です。

http://www.infoq.com/jp/news/2011/10/java-data-grid

Page 51: Java EE7 䛸㻌JCache

JSR-347 Spec Lead Manik Surtani氏とのインタビュー

o  分散。JSR 107の実装は分散化されていてもかまいません。一方、JSR 347の実装は分散化されていなければなりません。従って、JSR 347の方がデータストアの使い勝手を向上させるためにより機能豊富なAPIを提供します。例えば、グリッド上のデータの保存場所を制御するAPIや非同期のノンブロッキングAPI、実装の一貫性をサポートするAPIは、実装が分散化されているということを知っていなければ意味がありません。

Page 52: Java EE7 䛸㻌JCache

JSR-347 Spec Lead Manik Surtani氏とのインタビュー

o  Map/Reduceと分散コード実行。データがグリッド上に分散/パーティションされている場合、コードの実行をデータ側に移動させた方が他の方法よりも合理的な場合があります。JSR 347はこのようなことを実現するAPIも提供する予定です。

Page 53: Java EE7 䛸㻌JCache

JSR-347に対する VMWareの反対意見

o  VMware has serious concerns around the proposed JSR's relationship with JSR-107. While we note that some other EC members hope that the necessary harmonization can occur after the approval of this JSR, we would prefer to see such discussions take place before another potentially competing JSR is approved, and see that path as less risky.

Page 54: Java EE7 䛸㻌JCache

JSR-347に対する VMWareの反対意見

o  We do believe that this area is important and warrants interest from the JCP. The JSR-347 proposal includes useful functionality, but raises a serious risk of fragmentation and confusion.

o  We would prefer to see JSR-107 brought swiftly to a conclusion without excessive scope creep, allowing a new JSR then to be presented building upon it.

Page 55: Java EE7 䛸㻌JCache

Object Caching for Java

Functional Specification for Object Caching Service for Java (OCS4J), 2.0

http://jcp.org/aboutJava/communityprocess/jsr/cacheFS.pdf

Page 56: Java EE7 䛸㻌JCache

Objectの三つのタイプ

1. 決して変化しないオブジェクト n  staticで初期化すればいい

2. ユニークで使い捨てのオブジェクト n  使うたびにnewすればいい

3. 上記2つの中間のオブジェクト n  Javaは、先2つのタイプのオブジェクトは簡単に扱え

るが、第三のタイプのオブジェクトを扱うのは不便。

「第三のタイプ」とは、複数のリクエストをまたいで、ユーザーの間やプロセスの間で、 変化し共有されうる情報やオブジェクト。

Page 57: Java EE7 䛸㻌JCache

Object Caching Service for Java (OCS4J) の目的

o  Caching Service for Java (OCS4J)の目的は、アプリケーションが、リクエストやユーザーやプロセスをまたいで、オブジェクトを共有することを可能にすること。

o  このシステムは、任意のJavaオブジェクトを扱うことが出来る。全てのオブジェクトは、「名前」によって位置づけられ、プロセス中の全てのスレッドによって共有される。

Page 58: Java EE7 䛸㻌JCache

キャッシュされた オブジェクトのLife Cycle

o オブジェクトの生成 n  ユーザーが定義したLoaderで行われる n  不要な生成を避ける為に、キャッシュシステムと

の協調が必要 o オブジェクトの無効化

n  アプリから明示的に行うことも可能 n  “time to live” あるいは “idle time” に関連して n  キャッシュシステムの容量オーバー(設定可能)

o オブジェクトの削除

Page 59: Java EE7 䛸㻌JCache

キャッシュされた オブジェクトのLife Cycle

o  オブジェクトの削除 n  最近使われていないオブジェクト n  削除されたオブジェクトは、ディスクにスプール可能 n  スプールの決定は、ユーザーが定義したオブジェク

トの属性による

o  コールバック n  オブジェクトがキャッシュシステムで無効化あるいは

削除された時、登録されたコールバック・メソッドを呼び出すように出来る。

Page 60: Java EE7 䛸㻌JCache

キャッシュとプロセス

o  システムの単純性、可用性、パフォーマンスの為に、オブジェクト・キャッシュは、それぞれのプロセスに結びつけられている。

o  キャッシュ・システムでのオブジェクトの生成には、中央からのコントロールといったものは存在しない。

o  しかし、オブジェクトの更新と無効化についてはプロセス間の調整がある。 n  あるプロセスでオブジェクトが更新あるいは無効化

された時、その名前と関連情報は、他の全てのキャッシュのインスタンスにブロードキャストされる。

Page 61: Java EE7 䛸㻌JCache

GAEでのJCache の利用

Page 62: Java EE7 䛸㻌JCache

Cache インスタンスの取得

Cache cache; try { CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory(); cache = cacheFactory.createCache(Collections.emptyMap()); } catch (CacheException e) { // ... }

Page 63: Java EE7 䛸㻌JCache

値の設定と取得

String key; // ...         byte[] value; // ... // Put the value into the cache. cache.put(key, value); // Get the value from the cache. value = (byte[]) cache.get(key);

Page 64: Java EE7 䛸㻌JCache

有効期限の設定

Cache cache; Map props = new HashMap(); props.put(GCacheFactory.EXPIRATION_DELTA, 3600); try { CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory(); cache = cacheFactory.createCache(props); } catch (CacheException e) { // ... }

Page 65: Java EE7 䛸㻌JCache

値の有効期限は次のプロパティで制御

o  GCacheFactory.EXPIRATION_DELTA: 値を設定した時点から有効期限までを秒数で指定する整数値

o  GCacheFactory.EXPIRATION_DELTA_MILLIS: 値を設定した時点から有効期限までをミリ秒数で指定する整数値

o  GCacheFactory.EXPIRATION: 有効期限の日時を指定する java.util.Date

Page 66: Java EE7 䛸㻌JCache

設定ポリシーの設定

Map props = new HashMap(); props.put(MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT, true);

Page 67: Java EE7 䛸㻌JCache

o  MemcacheService.SetPolicy.SET_ALWAYS: キーに値が存在しない場合は値を追加し、そのキーの値が存在する場合は既存の値を置き換えます。これがデフォルトの設定です。

o  MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT: キーに値が存在しない場合は値を追加し、そのキーの値が存在する場合は何も実行しません。

o  MemcacheService.SetPolicy.REPLACE_ONLY_IF_PRESENT: キーに値が存在しない場合は何も実行せず、そのキーの値が存在する場合は既存の値を置き換えます。

Page 68: Java EE7 䛸㻌JCache

キャッシュの統計

CacheStatistics stats = cache.getCacheStatistics(); int hits = stats.getCacheHits(); int misses = stats.getCacheMisses();

Page 69: Java EE7 䛸㻌JCache

サポートされていない JCache 機能

o  JCache Listener API は、onPut リスナや onRemove リスナなど、アプリケーションの API 呼び出しの処理中に実行できるリスナについては一部サポートされています。onEvict など、バックグラウンド処理が必要なリスナはサポートされていません。

o  アプリケーションは、キャッシュ内に指定のキーがあるかどうかをテストすることはできますが、指定の値があるかどうかはテストできません(containsValue() はサポートされません)。

o  アプリケーションでキャッシュのキーまたは値の内容をダンプすることはできません。

o  アプリケーションで手動でキャッシュの統計をリセットすることはできません。

Page 70: Java EE7 䛸㻌JCache

o  非同期のキャッシュ読み込みはサポートされていません。

o  put() メソッドは、キーの以前の値を認識していても値を返さず、常に null を返します。

Page 71: Java EE7 䛸㻌JCache

JSR107 JCache 仕様

「一時的なメモリー内のJavaオブジェクトのキャッシングのAPIとセマンティックスを規定する。オブジェクトの生成、共有アクセス、スプーリング、無効化、複数のJVMをまたいだ整合性を含む。」

Page 72: Java EE7 䛸㻌JCache

経緯

o  2001年5月 JSRスタート o  2003年12月 CoherenceのCameron Purdy、

Spec Leadに o  2007年5月 EhCacheのGreg Luck、co-Spec

Leadに o  2012年4月 新しい体制 Brian Oliver (Oracle), Cameron Purdy (Oracle), Greg Luck,..., Billy Newport o  Early Draft 1, still in progress.

https://github.com/jsr107/jsr107spec

Page 73: Java EE7 䛸㻌JCache

現時点でのRIに 含まれているパッケージ

o  javax.cache o  javax.cache.annotation o  javax.cache.event o  javax.cache.mbeans o  javax.cache.spi o  javax.cache.transaction

https://github.com/jsr107/jsr107spec/tree/master/src/main/java/javax/cache

Page 74: Java EE7 䛸㻌JCache

Chapter 1 - Introduction

Page 75: Java EE7 䛸㻌JCache

目的

o  キャッシングは、アプリを劇的にスピードアップする、試されずみの、真実の方法である。

o  アプリは、生成するのに高価だが再利用可能なライフタイムを持つ一時的なデータを、しばしば、使うことがある。

o  例えば、サーブレットは、複数のデータベース、ネッチワークのコネクション、そして高価な計算から得られるデータから、Webページを生成する。これらのデータセットは、同じ、あるいは異なった時間のあいだ、再利用可能かもしれない。

Page 76: Java EE7 䛸㻌JCache

o  この仕様は、Javaオブジェクトのキャッシングの標準化を行い、その効果的な実装を可能とし、キャッシュのエクスパイア、相互排他制御、スプーリング、キャッシュの整合性といったものを実装する重荷を、プログラマーから取り除くようにしようとするものである。

Page 77: Java EE7 䛸㻌JCache

目標

o  Object Cache: このAPIは、Javaオブジェクトをキャッシュする。

o  Support for By-Value caching and optionally, By-Reference. 後者の参照はヒープの中に、前者では、キーと値は、両方とも、値に変換される。

o  Support for Flexible Implementations 仕様は、プロセスでの実装と、分散での実装の両方をサポートする。

Page 78: Java EE7 䛸㻌JCache

o  Java SE   この仕様はJava SEのもとで機能する。 o  Java EE

この仕様は、Java EEのもとで機能する。この仕様は、Java EE7に含まれることを目標としている。

o  Annotations この仕様は、ランタイムのキャッシュ・アノテーションを定義する。

o  Transactions トランザクションのオプショナルなサポート。ローカルとXAの双方が定義される。

Page 79: Java EE7 䛸㻌JCache

Chapter 2 - Caches

Page 80: Java EE7 䛸㻌JCache

キャッシュとは?

o  キャッシュは、一時的なデータを格納する場所である。それは、Mapに似たAPIを提供する。Mapと同様に、データはキーの値として格納される。

o  データは、Mapと同じく、ユニークな識別子であるキー経由でアクセスされる。与えられたキーに対して、キャッシュには一つのエントリーしか存在出来ない。

o  最も重要なプログラミングの対象物は、Cacheインターフェースである。Cacheへの呼び出しは、このインターフェースを通じて行われる。

Page 81: Java EE7 䛸㻌JCache

キャッシュの利用

o  データベースからのデータがキャッシュされるとよく思われている。もし、JPAを使っているなら、確かに、そういうことになる。

o  ただ、基本的には、作り出すのが高価で時間を要するものは、なんであれキャッシュに格納出来る。

Page 82: Java EE7 䛸㻌JCache

キャッシュの利用例

o  データベースの行のキャッシング o  プロセス中のNoSQLデータのキャッシング o  サーブレットのレスポンスのキャッシング o  クライアント側でのWebサービス呼び出しのキャ

ッシング o  イメージのレンダー等の高価な計算のキャッシング o  DOMのキャッシング

Page 83: Java EE7 䛸㻌JCache

キャッシュのKey/Value

o  KeyとValueに、特別の型の制限はない。 o  ただし、KeyとValueは、Nullであってはなら

ない。nullキーでのアクセスも、null valueを設定しようとした場合にも、NullPointerExceptionが返る。

Page 84: Java EE7 䛸㻌JCache

o  キャッシュは、 storeByValueをサポートしなければならない。その意味は、キー/バリューを、オブジェクトではない表現に変換する方法がなければいけないということである。 これは、典型的には、ネットワーク上で送信出来る、あるいは、永続的なストアに格納出来る、メモリー外での表現のことを意味する。

o  これを達成する一つの方法は、キー/バリューが、Serializableインターフェースを実装することである。ただ、実装には他の方法を用いることも出来る。Serializable以外の方法をサポートするスキームは、実装依存であり、実装間の移植性を必要とはしない。

Page 85: Java EE7 䛸㻌JCache

キャッシュを見つける

o CacheManagerは、キャッシュを管理する。 o キャッシュは、名前で同定され、アクセスされる。 o キャッシュへの参照は、次のようにgetCache

で得られる。 Cache cache = cacheManager.getCache(“Greg’s Cache”);

Page 86: Java EE7 䛸㻌JCache

Chapter 3 - Cache Operations

Page 87: Java EE7 䛸㻌JCache

Cache Operations

o  Cacheインターフェースは、 ConcurrentMapパターンに基づいている。ただ、それを継承したものではない。

o  というのも、 ConcurrentMap (とMap)のメソッドのあるものは、分散環境では、効率的ではないシグニチャーをもつからだ。例えば、Map.putは、ある値を返すのだが、たいていの場合、それは無視される。

Page 88: Java EE7 䛸㻌JCache

Cache メソッド

o  V get(K key) o  Map<K,V> getAll(Set<?

extends K> keys) o  boolean

containsKey(K key) o  Future<V> load(K key) o  Future<Map<K,? extends

V>> loadAll(Set<? extends K> keys)

o  CacheStatistics getStatistics()

o  void put(K key, V value) o  V getAndPut(K key,

      V value)

o  void putAll(Map<? extends K,? extends V> map)

o  boolean putIfAbsent (K key, V value)

o  boolean remove(K key) o  boolean remove 

(K key,V oldValue) o  V

getAndRemove(K key) o  boolean replace(K key,

V oldValue, V newValue) o  boolean replace(K key,

V value)

Page 89: Java EE7 䛸㻌JCache

Cache メソッド

o  V getAndReplace (K key, V value)

o  void removeAll(Set<? extends K> keys)

o  void removeAll() o  CacheConfiguration<K,V

> getConfiguration() o  boolean

registerCacheEntryListener(CacheEntryListener<? super K,? super V> cacheEntryListener)

o  Iterator<Cache.Entry<K,V>> iterator()

o  boolean unregisterCacheEntryListener(CacheEntryListener<?,?> cacheEntryListener)

o  Object invokeEntryProcessor(K key, Cache.EntryProcessor<K,V> entryProcessor)

o  String getName() o  CacheManager

getCacheManager() o  <T> T

unwrap(Class<T> cls)

Page 90: Java EE7 䛸㻌JCache

Cache Entry Expiration

o  キャッシュ中のエントリーは、最終更新時あるいは最終アクセス時間に基づいて、エクスパイアする。javax.cache.CacheConfiguration.ExpiryTypeによってコントロールされる。

Page 91: Java EE7 䛸㻌JCache

Read-Through Caching

o  read-through キャッシュは、read-through ではないキャッシュと全く同じように振る舞う。ただ、エントリーがキャッシュに見つからなかった場合、get()とgetAll()が、CacheLoaderを呼び出す点が異なる。

Page 92: Java EE7 䛸㻌JCache

Write-Through Caching

o  Proxyである。どのような変化も、常に、CacheWriterを呼び出す。

o  write-through モードの時、removeAllNoWriteThroughは、キャッシュのみを全消去する。

ライター

Page 93: Java EE7 䛸㻌JCache

参考:eXtreme Scale 後書きキャシング

o  後書きキャッシングは、ローダー・プラグインへの更新情報を 非同期でキューに入れます。eXtreme Scale トランザクションをデータベース・トランザクションから分離することにより、マップの更新、挿入、 および除去の、 パフォーマンスを改善 できます。非同期更新は、時間ベース の遅延 (例えば、5 分)、 またはエント リー・ベースの遅延 (例えば、1000 エントリー) 後に 実行されます。

http://publib.boulder.ibm.com/infocenter/wxsinfo/v7r1/index.jsp?topic=%2Fcom.ibm.websphere.extremescale.over.doc%2Fcxswritethr.html

Page 94: Java EE7 䛸㻌JCache

CacheLoader o  CacheLoaderインターフェースは、キャッシュのプリ・ロ

ードと、キャッシュミス時の特別なアクションを可能とする2つの場合に用いられる。

o  後者の場合は、例えば、read-throughが実装されている場合には、CacheLoaderが利用される。

Page 95: Java EE7 䛸㻌JCache

CacheEntryListener n  CacheEntryCreatedListener n  CacheEntryUpdatedListener n  CacheEntryRemovedListener n  CacheEntryReadListener

o  Listenerは、次のいずれかの通知スコープに登録される。 n  local – このJVMの中でイベントが発生する n  remote – リモートのJVMでイベント発生

Page 96: Java EE7 䛸㻌JCache

Chapter 4 - Cache Managers

Page 97: Java EE7 䛸㻌JCache

Cache Managers

o CacheManagerは、キャッシュの集まりで、そのコンテナーである。コンテナーとして、それは、キャッシュのライフサイクルの全ての局面を管理する。

Page 98: Java EE7 䛸㻌JCache

Cache Managersの機能

1.  キャッシュを名前で見つけ出す機能 2.  Transactionマネージャにとって、XA Resourceとして

働く。 3.  キャッシュのユニットに対して設定の対応をする。 4.  自身が起動されると、全ての設定されたキャッシュを起動

する。 5.  CacheManagerがシャットダウンされると、その内部の

全てのキャッシュはシャットダウンされる。 6.  分散キャッシュのクラスターの統合ポイントである。起動

時には、必要なリソースを割り当て、シャットダウン時には、それらを解放する。

Page 99: Java EE7 䛸㻌JCache

Cache Managersの機能

7.  デフォールトのキャッシュのテンプレートを提供し、新しいキャッシュが意味のあるデフォールトで作られるようにする。

8.  シングルトンとして、ただ一つのCacheManagerしか存在しない場合に用いられることもあるし、もっと複雑なケースでは、VMあたり複数のCacheManagerがもちられることもある。

9.  キャッシュの繰り返しや追加や削除をサポートする。

Page 100: Java EE7 䛸㻌JCache

Construction

o シングルトンのCacheManagerは、次のように構成され、参照される。

  CacheManager.getInstance() o インスタンスの構成

複数のCacheManagerのインスタンスは、次のようにして生成される。

  new CacheManager()

Page 101: Java EE7 䛸㻌JCache

Default CacheManager o  利用を簡単にするために、実装はデフォールトの

設定を提供すべきである。そうすれば、ユーザによって提供される実装に特有の設定ファイルが無い場合でも、CacheManagerを生成することが出来、キャッシュはそれに追加される。

o  Java SEが、この仕様と参照実装を追加して、こうした機能がJava SE でも利用可能になることが期待されている。

Cache<Integer, Date> myCache2 = cacheManager. <Integer, Date>createCacheBuilder("myCache2"). build();

Page 102: Java EE7 䛸㻌JCache

Cache Configuration

Cache<Integer, String> myCache1 = cacheManager. <Integer, String>createCacheBuilder("myCache1"). setCacheLoader(cl). setStoreByValue(true). setReadThrough(true). setWriteThrough(false). setStatisticsEnabled(true). setTransactionEnabled(false). registerCacheEntryListener(listener1,          NotificationScope.LOCAL, false). registerCacheEntryListener(listener2,         NotificationScope.LOCAL, false). build();

Page 103: Java EE7 䛸㻌JCache

simple example

String cacheName = "sampleCache"; CacheManager cacheManager = Caching.getCacheManager(); Cache<Integer, Date> cache = cacheManager.getCache(cacheName); if (cache == null) { cache = cacheManager.<Integer,Date>createCacheBuilder(cacheName).build(); } Date value1 = new Date(); Integer key = 1; cache.put(key, value1); Date value2 = cache.get(key);

Page 104: Java EE7 䛸㻌JCache

o  boolean putIfAbsent(K key, V value) if (!cache.containsKey(key)) { cache.put(key, value); return true; } else { return false; }

Page 105: Java EE7 䛸㻌JCache

Interface CacheManager o  <K,V> CacheBuilder<K,V> createCacheBuilder(String

cacheName) o  <K,V> Cache<K,V> getCache(String cacheName) o  Iterable<Cache<?,?>> getCaches() o  String getName() o  Status getStatus() o  UserTransaction getUserTransaction() o  boolean isSupported(OptionalFeature optionalFeature) o  boolean removeCache(String cacheName) o  void shutdown() o  <T> T unwrap(Class<T> cls)

Page 106: Java EE7 䛸㻌JCache

Interface CacheBuilder<K,V>

o  Cache<K,V> build() o  CacheBuilder<K,V>

registerCacheEntryListener(CacheEntryListener<K,V> cacheEntryListener)

o  CacheBuilder<K,V> setCacheLoader(CacheLoader<K,? extends V> cacheLoader)

o  CacheBuilder<K,V> setCacheWriter(CacheWriter<? super K,? super V> cacheWriter)

o  CacheBuilder<K,V> setExpiry(CacheConfiguration.ExpiryType type, CacheConfiguration.Duration duration)

o  CacheBuilder<K,V> setReadThrough(boolean readThrough)

Page 107: Java EE7 䛸㻌JCache

Interface CacheBuilder<K,V>

o  CacheBuilder<K,V> setStatisticsEnabled(boolean enableStatistics)

o  CacheBuilder<K,V> setStoreByValue(boolean storeByValue)

o  CacheBuilder<K,V> setTransactionEnabled(IsolationLevel isolationLevel, Mode mode)

o  CacheBuilder<K,V> setWriteThrough(boolean writeThrough)

Page 108: Java EE7 䛸㻌JCache

Interface CacheLoader<K,V>

o  CacheLoaderは、read-throughキャッシングで利用され、データをキャッシュにロードする。

o  Cache.Entry<K,V> load(K key) Loads an object.

o  Map<K,V>loadAll(Iterable<? extends K> keys) Loads multiple objects.

Page 109: Java EE7 䛸㻌JCache

Interface CacheWriter<K,V>

o  CacheWriterは、 背後にあるリソースへのwrite-throughキャッシングとwrite-behind キャッシングで利用される。

o  void delete(Object key) o  void deleteAll(Collection<?> entries) o  void write(Cache.Entry<K,V> entry) o  void writeAll(Collection<Cache.Entry

<? extends K,? extends V>> entries)

Page 110: Java EE7 䛸㻌JCache

Class Caching

o  JDKのServiceLoaderのSPI規約を利用して、CacheManagers を生成する為のFactoryである。

o  プロバイダが発見される為に、そのjarファイルは、次のように、CachingProviderを実装したクラス名のリソースを含まなければならない。

META-INF/services/ javax.cache.spi.CachingProvider 例えば、参照実装では、この中味は次のようになる。 "javax.cache.implementation.RIServiceFactory"

Page 111: Java EE7 䛸㻌JCache

Class Caching

o  もしも、一つ以上のCachingProviderが見つかったら、 getCacheManagerFactoryは、例外を投げる。

o  Cachingクラスはまた、このfactoryで生成された全てのCacheManagersの追跡をする。getCacheManager()を、再び呼び出した時には、同じ CacheManagerが返る。

Page 112: Java EE7 䛸㻌JCache

Interface CachingProvider o  CacheManager factory プロバイダによって実装される

べきインターフェース。 CacheManagerを生成する為に、 Cachingクラスによって呼び出される。

o  このインターフェースの実装は、引数を持たないpublicなコンストラクタを持たなければならない。

o  CacheManagerFactory getCacheManagerFactory() Returns the singleton CacheManagerFactory.

o  boolean isSupported(OptionalFeature optionalFeature) Indicates whether a optional feature is supported by this implementation

Page 113: Java EE7 䛸㻌JCache

キャッシュは、 CacheManagerの中にある

o  キャッシュは、キャッシュ・クラスタとの統合のようなCacheManager の機能を必要とすることがあるので、CacheManagerの外部で起動されてはならない。 キャッシュは、まず最初に、追加されねばならない。

o  それらが設定ファイルにあれば、CacheManagerは、起動時に、自動的に追加を行う。動作中のCacheManager に、プログラムを通じてキャッシュを追加することも可能である。

Page 114: Java EE7 䛸㻌JCache

Chapter 5 - Transactions

Page 115: Java EE7 䛸㻌JCache

Transactions

o  トランザクションは、この仕様のオプショナルな要件である。トランザクションは、JTA仕様で提供された意味を持つ。もし、実装されれば、トランザクションはここで規定されたように動作する必要がある。

o  2つのトランザクション・モデルがサポートされている。 1.  グローバル・トランザクション:XAトランザクションとし

て知られているもの 2.  ローカル・トランザクション:トランザクション境界は、

CacheManager

Page 116: Java EE7 䛸㻌JCache

o  トランザクションを提供する動機は、キャッシュにとってデータベース、メッセージキュー、その他のXAリソースと強い整合性を保ち続けることが、しばしば、非常に重要になるからである。

o  トランザクションのサポート無しには、キャッシュのエントリーは、これらと整合的であるという保証は出来なくなる。

o  あるキャッシュは、ローカルキャッシュか、XAトランザクションの一つをサポート出来るが、その両方を同時にはサポート出来ない。

Page 117: Java EE7 䛸㻌JCache

XA Transactions

o キャッシュのXAトランザクションは、JTAの仕様と選択された隔離レベルに基づいて機能する。

o XAトランザクションは、 Transaction Managerの存在を必要とする。

o あるXAトランザクションのコンテキスト外のXAキャッシュを操作しようと試みると、CacheExceptionが引き起こされる。

Page 118: Java EE7 䛸㻌JCache

トランザクション・サンプル

//Get a global transaction assuming in a // Java EE app server UserTransaction utxg = jndiContext.lookup(“java:comp/UserTransaction”); // start the transactions utxg.begin(); // do work cache1.put(“key1”, “value”); cache2.remove(“key3”); cache3.put(“key5”, “value4”); // commit the transactions utxg.commit();

Page 119: Java EE7 䛸㻌JCache

Enlistment o  Enlistmentとは、トランザクション・マネージャが、あるX

Aリソースがあるトランザクションに参加しようとしていると、それによって告げられるプロセスである。

o  javax.transaction.xa パッケージは、トランザクション・マネージャとリソース・マネージャとの契約を定義している。それは、トランザクション・マネージャが、JTAトランザクションにおいて、(リソース・マネージャ・ドライバーによって与えられる)リソース・オブジェクトのリストへの登録とリストからの削除を可能にする。

Page 120: Java EE7 䛸㻌JCache

o  Enlistmentsは、 TransactionManager.getTransaction().enlistResource(XAResource xaRes)を用いることで終了する。

o  TransactionManagerへの参照が獲得される方法は、JTAの仕様では定義されていない。Java EEアプリケーション・サーバは、典型的には、参照を取得する為に、ベンダー固有の、よく知られているJNDIパスを利用している。

o  XAリソースの最初のオペレーションでは、TransactionManagerによって、start() が呼ばれる。

o  XAは、コネクション指向である。 キャッシュは、コネクションを信じてはいない。これらは、インピーダンス・ミスマッチを生み出す。

Page 121: Java EE7 䛸㻌JCache

o  我々がコネクションを閉じることは無いので、XAResource.end()が呼びだされることはない。

o  我々は、two-phaseコミット・プロトコルがはじまる前にトランザクション・マネージャが、我々の為にend()を呼び出すことを期待する。(こうしたことは、JTAの仕様では、全く規定されていないとしても) これが、ほとんど全てのTransactionManagersの振る舞いである。

Page 122: Java EE7 䛸㻌JCache

o  JTAの仕様は次のことを要求している。 「同一のリソースを使って、複数のトランザクション・コンテキストをインターリーブすることは、それぞれのトランザクション・コンテキスト・スイッチに対してXAResource.start と XAResource.endが適切に呼び出される限りで、トランザクション・マネージャによって可能となるだろう。リソースが異なるトランザクションで利用されるたびごとに、このリソースが関連づけられていた以前のトランザクションに対して、必ず、XAResource.endメソッドが呼び出され、現在のトランザクション・コンテキストに対して、必ず、XAResource.startが呼び出されなければならない。」

Page 123: Java EE7 䛸㻌JCache

o  もしXAResourceがCacheManagerのレベルにあったとすると、我々は、endを呼び出さないのだから、このことは、CacheManagerをまたいでは、同時には、一つのトランザクションのみが実行可能であることを意味する。これが、可能な実装である。

o  それぞれのトランザクションごとに、ある新しいXAResource が生成されて、一つのキャッシュ・マネージャが、トランザクションがあるたびに、沢山のXAResourceをオープンすることが、示唆される。このようにして、並列トランザクションがサポートされる。インターリービングの問題は、回避される。

Page 124: Java EE7 䛸㻌JCache

o  可能な別の実装は、キャッシュの操作のたびごとに、XAResourceを生成することである。これは、高い並列性を実現するが、より多くの、高価なenlistResource()メソッドの呼び出しを要求する。

Page 125: Java EE7 䛸㻌JCache

Recovery

o  Cachesは、JTAで定義されている、リカバリー・プロトコルを実装しなければならない。特に、 XAResource.recover()は、必ず、サポートしなければならない。

o  永続するストアを持たず、新しいプロセスが空のキャッシュで再起動されるような、ローカルなプロセス中のキャッシュの場合には、recover()が、javax.transaction.xa.Xid[]の空な配列を返すことが認められる。

o  トランザクション・マネージャは、この場合には、Heuristic Exceptionを報告するかもしれない。

Page 126: Java EE7 䛸㻌JCache

o  このことは、待機中のトランザクションが、他のXAResourcesに対して、正しくリカバーされることを妨げはしないだろう。さらに、ローカル・キャッシュは、読み出しのいかなる試みに対しても空なので、影響される値はキャッシュ・ミスとなり、この値に対するユーザのロジックは、影響を受けない。

Page 127: Java EE7 䛸㻌JCache

Local Transactions

o  トランザクションをサポートするキャッシュは、4つの隔離レベルを持つローカル・トランザクションをサポートするだろう。

o  ローカル・トランザクションは、トランザクション・マネージャの存在を要求しない。

o  ローカル・トランザクションは、分散であれローカルであれ、同一のキャッシュ・マネージャ内の、一つ以上のキャッシュに対する複数のキャッシュ操作をまたいだ、シングル・フェーズのコミットを可能とする。

Page 128: Java EE7 䛸㻌JCache

o  このことは、CacheManagerに対する複数の変更を、全て、単一のトランザクションで適用させることになる。

o  もし、データベースのような他のリソースに対して変更を適用することも望むなら、それらに対するトランザクションを開いて、整合性を保証する為に、手動でコミットとロールバックを取り扱う必要がある。(あるいは、XA Transactionsを使用する)

o  例えば、キャッシュAに対して2つのputを行い、キャッシュBに対して一つのremoveを行い、キャッシュCに対して4つのputを行うとする。これらは、全て、単一のローカル・トランザクションの中に納められる。

Page 129: Java EE7 䛸㻌JCache

o  JTA APIは、ローカル・トランザクションのコントロールに使用される。

o  javax.transaction.UserTransactionインターフェースは、アプリケーションにトランザクション境界をプログラムでコントロールする能力を与える。

Page 130: Java EE7 䛸㻌JCache

//Get a transaction UserTransaction utx = cacheManager.getUserTransaction(); // start a transaction utx.begin(); // do work cache1.put(“key1”, “value”); cache2.remove(“key3”); // commit the work utx.commit();

Page 131: Java EE7 䛸㻌JCache

o  全てのローカル・トランザクションに関しての、ベスト・プラクティスは、これらのステップを、try-catchブロックの中に置いて、もし、例外が投げられたら、rollback()を呼ぶことである。(詳細は、JTAの仕様を参照されたい)

o  ローカル・トランザクション・コンテキストの外部からキャッシュを操作する試みは、javax.cache.transaction.TransactionExceptionを引き起こすだろう。

Page 132: Java EE7 䛸㻌JCache

o  単一のスレッドが、XAトランザクションとローカル・トランザクションを開始することは可能である。キャッシュ操作は、トランザクション・コンテキストが存在する故に、XAならびにローカルなトランザクション・キャッシュの双方に受け入れられる。しかしながら、トランザクションは分離している。

o  別のプログラム例(EJB言語で、bean managed)、cache1とcache2はローカル・トランザクションとして設定され、cache3はXAトランザクションとして設定されているは、それを示している。次のようになるだろう。

o  ただ、これは動くのだが、一つのトランザクションが成功し、他のが失敗することもあり得るので、特に、役に立つという訳でもない。

Page 133: Java EE7 䛸㻌JCache

//Get a local transaction UserTransaction utxl = cacheManager.getUserTransaction(); //Get a global transaction assuming in a Java EE app server UserTransaction utxg = jndiContext.lookup(“java:comp/UserTransaction”); // start the transactions utxl.begin(); utxg.begin(); // do work cache1.put(“key1”, “value”); cache2.remove(“key3”); cache3.put(“key5”, “value4”); // commit the transactions utxl.commit(); utxg.commit();

Page 134: Java EE7 䛸㻌JCache

o  ローカル・トランザクションは、すべてCacheExceptionのサブクラスである、自身の例外を持っている。

o  TransactionException n  一般的な例外

o  TransactionInterruptedException n  キャッシュがトランザクションの処理中に、Thread.interrupt()

が呼ばれた時 o  TransactionTimeoutException

n  トランザクションのタイムアウトが過ぎてから、キャッシュの操作、あるいは、コミットが呼ばれた場合。

Page 135: Java EE7 䛸㻌JCache

Recovery

o  Recoveryは、XAトランザクションに関連している。 Tローカル・トランザクションでは、コミット以前にクラッシュした場合、変化は、隔離レベルにディペンドする。

Page 136: Java EE7 䛸㻌JCache

Chapter 6 - Isolation Levels

Page 137: Java EE7 䛸㻌JCache

Isolation Levels

o  キャッシュの隔離レベルは、生成時に設定され、そのキャッシュのライフサイクルを通じて、変更不能なままにとどまる。

  隔離レベルには、次の4つがある。 o  READ_COMMITTED o  READ_UNCOMMITTED o  REPEATABLE_READ o  SERIALIZABLEの

Page 138: Java EE7 䛸㻌JCache

READ_COMMITTED

o  内容の変化は、COMMIT が呼ばれるまで、ローカル・キャッシュでも分散キャッシュでも、他のトランザクションには見えない。

o  その時まで、次のいずれかの実装が自由である。 n  古いコピーを返す n  コミット、あるいは、ロールバックが呼ばれるまでブロックする。

o  両方のアプローチとも、READ_COMMITTED 隔離レベルを満たす。

Page 139: Java EE7 䛸㻌JCache

READ_UNCOMMITTED

o  キャッシュの変化は、ローカル・キャッシュでも分散キャッシュでも、実装上の伝搬の遅延に従いながら、トランザクションが利用されなかったように、ただちに他のトランザクションに見える。

o  commit時には、値の変化は観測されない。 o  rollback時には、値は、以前の値に戻される。これは、

もちろん、目に見える変化だ。 o  timeout時には、JTA の仕様は、ロールバックが呼ば

れると記述している。だから、timeoutでも、古い値に戻される。正確にいえば、いつrollbackが起きるかは、実装依存である。

Page 140: Java EE7 䛸㻌JCache

SERIALIZABLE

o  内容の変化は、COMMIT が呼ばれるまで、ローカル・キャッシュでも分散キャッシュでも、他のトランザクションには見えない。

o  さらに、他のトランザクションによって起こされたキャッシュの変化は、そのトランザクションが完了するまで、見えない。

o  SERIALIZABLE隔離レベルは、 REPEATABLE_READの上に、Phantom readsからの、さらに進んだ保護を提供する。

Page 141: Java EE7 䛸㻌JCache

o  An alternative is to exclusively write lock a collection of keys of interest before starting your transaction. We could use lockAll(Collection keys). This would create a ReadWrite lock. Other transactions would block until this transaction.

o  This behaviour could be achieved pessimistically with a ReadWrite lock over the entire cache or also achieved optimistically by triggering a RollbackException if any changes made to the keys used (for reads or writes) in this transaction have been made.

Page 142: Java EE7 䛸㻌JCache

REPEATABLE_READ

o  Mutating changes are not visible to other transactions in a local cache or a distributed cache until COMMIT has been called.

o  Further no changes to the cache made by other transactions for keys once they have or written by this transaction are visible to this transaction until it completes.

o  This behaviour could be achieved pessimistically with a ReadWrite lock acquired over the keys as they are used or also achieved optimistically by triggering a RollbackException if any changes made to the keys used (for writes) in this transaction have been made.

Page 143: Java EE7 䛸㻌JCache

Chapter 7 – Caching Annotations

Page 144: Java EE7 䛸㻌JCache

Caching Annotations

o  この章では、Java Caching 1.0 仕様で定義された、アノテーションについて議論する。アノテーションは、この仕様のオプショナルな部分であり、独立したライブラリーとしても実装可能である。

o  アノテーション・クラスのJavaDocは、機能の詳細な記述として読まれるべきである。

Page 145: Java EE7 䛸㻌JCache

Annotations Overview

o アノテーションとそのサポートクラスは、javax.cache.annotationパッケージにある。

Page 146: Java EE7 䛸㻌JCache

Annotation Inheritance and Ordering

o  この仕様は、アノテーションの継承について、Java仕様のCommon Annotations の2,1節に従っている。

o  この仕様外のアノテーションに関する、インターセプターの実行の順序については定義されておらず、アノテーションをサポートする実装に委ねられている。

Page 147: Java EE7 䛸㻌JCache

Multiple Annotations

o  一つのメソッドには、一つのメソッド・レベルのキャッシング・アノテーションのみが指定でき、パラメータでは、一つのパラメータ・レベルのアノテーションのみが指定出来る。

o  もし、一つ以上のアノテーションが、メソッドないしはパラメータに指定された場合には、アプリの初期化時、あるいは、メソッドの呼び出し時に、CacheAnnotationConfigurationException が投げられねばならない。

Page 148: Java EE7 䛸㻌JCache

@CacheDefaults

o  @CacheDefaultsは、クラス内で利用されるキャッシングに関連した全てのアノテーションのデフォールトのプロパティの値を定義するのに用いられる、クラス・レベルのアノテーションである。

o  cacheName, cacheResolverFactory, cacheKeyGeneratorといったプロパティが指定される。ただし、全て、オプショナルである。

o  もし、@CacheDefaultsがクラスに指定されて、メソッド・レベルのキャッシング・アノテーションが存在しない場合、 @CacheDefaultsアノテーションは無視される。

Page 149: Java EE7 䛸㻌JCache

o  次の例は、このクラスのキャッシュのデフォールトとして利用される、”cities”という名前のキャッシュを指定している。

o  getCityメソッドの、@CacheResultアノテーションは、実行時にこのキャッシュの名前を利用する。

@CacheDefaults(cacheName=”cities”) public class CitySource { @CacheResult public City getCity(int lat, int lon) { //... } }

Page 150: Java EE7 䛸㻌JCache

package my.app; @CacheDefaults(cacheName="domainCache") public class DomainDao { @CacheResult public Domain getDomain(String domainId, int index) { ... } @CacheRemoveEntry public void deleteDomain(String domainId, int index) { ... } @CacheResult(cacheName="allDomains") public List<Domain> getAllDomains() { ... } }

Page 151: Java EE7 䛸㻌JCache

@CacheResult o  @CacheResultは、メソッド・レベルのアノテーションで

ある。その返り値がキャッシュされることを、メソッドにマークする為に用いられる。この時、キーは、メソッド・パラメータから生成され、同一のパラメータでのその後の呼び出しでキャッシュは、このキーを返す。

o  @CacheKeyParam アノテーションは、キーの生成において、パラメータのサブセットを選択するのに利用されうる。

Page 152: Java EE7 䛸㻌JCache

o  オプション 1.  cacheNullプロパティを通じて、返り値nullのキャッシュをコン

トロールする 2.  オプショナルなキャッシングと名前を持つキャッシュ自身の例外

の再発行。キャッシュ固有の例外の機能を含む。 3.  Cacheが呼ばれた時、オプションで、事前実行をスキップする。

アノテーションをつけられたメソッドが、常に実行され、返り値がキャッシュにおけれるべき時には役に立つ。

o  @CacheResult は、staticなメソッドに置かれた場合には、無視される。

Page 153: Java EE7 䛸㻌JCache

package my.app; public class DomainDao { @CacheResult public Domain getDomain(String domainId, int index) { ... } }

package my.app; public class DomainDao { @CacheResult public Domain getDomain(@CacheKey String domainId, Monitor mon) { ... } }

Page 154: Java EE7 䛸㻌JCache

@CachePut o  @CachePutは、メソッド・レベルのアノテーションで、そ

のメソッドの引数の一つがキャッシュに格納されるべきことをマークする。一つの引数は、それがキャッシュされるべきことを示す為に、@CacheValue アノテーションでマークされねばならない。

o  もし、@CacheValueアノテーションが指定されなければ、アプリの初期化時あるいはメソッドの呼び出し時に CacheAnnotationConfigurationExceptionが投げられねばならない。

o  @CacheKeyParam アノテーションは、キー生成時にパラメータのサブセットを選択するのに用いられるが、@CacheValueアノテーションのパラメータは、キー生成に含まれることは無い。

Page 155: Java EE7 䛸㻌JCache

o  オプション 1.  cacheNullプロパティを通じて、返り値nullのキャッシュをコン

トロールする 2.  Cache.putの呼び出しが、このメソッドの実行以前、あるいは

実行後に起きるのかを指定する。 3.  呼び出しの後に、キャッシングが起きれば、アノテートされたメソ

ッドからの例外は、Cache.put呼び出しをキャンセル出来る。 o  @CachePutは、staticなメソッドに置かれた場合には

、無視される。

Page 156: Java EE7 䛸㻌JCache

package my.app; public class DomainDao { @CachePut(cacheName="domainCache") public void updateDomain(String domainId, int index, @CacheValue Domain domain) { ... } }

@CachPutでアノテートされたメソッドが呼び出された時、CachKeyが生成され、指定されたキャッシュ上でCache.put(Object, Object)が呼び出され、@CacheValueでマークされた値を、キャッシュに格納する。 Null値は、デフォールトではキャッシュされるが、この振る舞いは、cacheNull()プロパティで、無効にできる。

Page 157: Java EE7 䛸㻌JCache

@CacheRemoveEntry

o  @CacheRemoveEntryは、メソッド・レベルのアノテーションで、エントリー中のメソッドの呼び出しの結果が指定されたキャッシュで削除されることをマークする。

o  @CacheKeyParam アノテーションは、キーの生成において、パラメータのサブセットを選択するのに利用される。

o  オプション 1.  Cache.removeの呼び出しが、このメソッドの実行以前、あるい

は実行後に起きるのかを指定する。 2.  呼び出し後に削除が起きれば、アノテートされたメソッドによって

投げられた例外は、Cache.remove呼び出しをキャンセルできる。 o  @CacheRemoveEntryは、staticなメソッドに置かれ

た場合には、無視される。

Page 158: Java EE7 䛸㻌JCache

package my.app; public class DomainDao { @CacheRemoveEntry(cacheName="domainCache") public void deleteDomain(String domainId, int index) { ... } }

Page 159: Java EE7 䛸㻌JCache

@CacheRemoveAll o  @CacheRemoveAllは、メソッド・レベルのアノテーショ

ンで、メソッドの呼び出しの結果のエントリー全てが、指定されたキャッシュで削除されることをマークする。

o  オプション 1.  Cache.removeAllの呼び出しが、このメソッドの実行以前、あ

るいは実行後に起きるのかを指定する。 2.  呼び出し後に削除が起きれば、アノテートされたメソッドによっ

て投げられた例外は、Cache.removeAll呼び出しをキャンセルできる。

o  @CacheRemoveAllは、staticなメソッドに置かれた場合には、無視される。

Page 160: Java EE7 䛸㻌JCache

package my.app; public class DomainDao { @CacheRemoveAll(cacheName="domainCache") public void deleteAllDomains() { ... } }

デフォールトの振る舞いでは、アノテートされたメソッドが呼び出された後に、Cache.removeAll()が呼ばれる。 この振る舞いは、afterInvocation() をfalseにすることで変更出来る。この場合、Cache.removeAll()は、アノテートされたメソッドが呼び出される前に呼ばれる。

Page 161: Java EE7 䛸㻌JCache

@CacheKeyParam

o  @CacheKeyParamは、パラメータ・レベルのアノテーションで、パラメータがCacheKeyGeneratorを通じてCachKeyを生成するのに利用されることをマークする。

o  実行時、@CacheKeyParamでアノテートされたパラメータは、 CacheKeyInvocationContext.getKeyParameters() アレーの中に置かれる。.

o  @CacheResult, @CachePut, @CacheRemoveEntryと一緒に使うことは出来ない。

Page 162: Java EE7 䛸㻌JCache

@CacheValue

o  @CacheValueは、パラメータ・レベルのアノテーションで、@CachePutでアノテートされたメソッドの、キャッシュされるべきパラメータをマークするのに用いられる。@CachePutでアノテートされたパラメータは、CacheKeyInvocationContext.getKeyParameters() アレーに含まれてはいけない。.

o  @CachePutと一緒に用いられる。

Page 163: Java EE7 䛸㻌JCache

Cache Resolution

o  メソッド・レベルのアノテーションは、全て、CacheResolverFactory の仕様とキャッシュを決定する為に用いられるキャッシュの名前が、実行時に相互に作用することを可能にする。

Page 164: Java EE7 䛸㻌JCache

Cache Name

o  もし、キャッシュの名前が、メソッド・レベルのアノテーションでも、@CacheDefaults アノテーションでも指定されていなければ、名前は、次のように生成される。

o  package.name.ClassName.methodName(package.ParameterType,package.ParameterType)

o  @CacheResultは、追加的に、 exceptionCacheNameプロパティを持っている。もし、この名前が指定されていなければ、デフォールトの例外キャッシュ名も例外キャッシュも利用されない。

Page 165: Java EE7 䛸㻌JCache

CacheResolverFactory

o  指定されたCacheResolverFactoryは、 毎回のアノテートされたメソッドの呼び出しのたびに利用されるCacheResolverを決定する為に、アノテートされたメソッドについて、正確に、一回呼ばれねばならない。

o  アノテートされたメソッドが実行されると、以前に取得されたCacheResolverが、CacheInvocationContextに基づいて利用すべきキャッシュを決定する為に用いられる。

o  javax.cache.annotation.CacheResolverFactory がアノテーションと@CacheDefaultsで指定されると、デフォールトのCacheResolverFactory のロジックが利用される。

Page 166: Java EE7 䛸㻌JCache

o  デフォールトの CacheResolverFactoryのルール: 1.  Caching.getCacheManager()を通じて、利用する

CacheManager を取得する。 2.  キャッシュの名前で、CacheManager.get(String)を呼ぶ。 3.  Cacheが返らなかったら、CacheManager.createCacheBuilder

を使って、キャッシュを生成する。 4.  見つかった/生成されたキャッシュをラップし、常にキャッシュを返

すCacheResolverを生成する。 o  もし、CacheResolverFactoryが例外を投げたら、そ

の例外は、CacheResolverFactoryの実行をトリガーしたアプリケーション・コードまで、伝搬されねばならない。

Page 167: Java EE7 䛸㻌JCache

CacheResolver o  CacheResolverは、CacheResolver ファクトリーによ

って返えされる。このことは、それが返されるアノテートされた全てのメソッドの呼び出しのたびに、 呼び出され、この呼び出しに利用されるキャッシュを返す。

o  もし、CacheResolverが例外を投げたら、その例外は、CacheResolverの実行をトリガーしたアプリケーション・コードまで、伝搬されねばならない。

Page 168: Java EE7 䛸㻌JCache

Key Generation

o  @CacheResult, @CachePut, @CacheRemoveEntryアノテーションは、全て、キャッシュ・キーが生成されることを要求する。これらのアノテーションの全ては、 CacheKeyGeneratorの実装の仕様に従う。

o  指定されたCacheKeyGeneratorは、アノテートされたメソッドの呼び出しのたびに、一回だけ呼ばれる。アノテートされたメソッドと現在の呼び出しの情報は、 CacheKeyInvocationContextによって与えられる。

Page 169: Java EE7 䛸㻌JCache

o  開発者がキーで利用されるように指定した、メソッドのパラメータは、getKeyParameters() メソッドで返されるCacheInvocationParameterアレーに含まれる。カスタムのCacheKeyGenerator は、CacheKeyを生成する為に、それが利用可能ないかなる情報も利用出来る。

o  もしjavax.cache.annotation.CacheKeyGenerator と@CacheDefaultsがアノテーションに指定されれば、デフォールトのCacheKeyGeneratorが利用されねばならない。

Page 170: Java EE7 䛸㻌JCache

o  デフォールトのCacheKeyGeneratorのルール: 1.  CacheKeyInvocationContext.getKeyParameters()で

返されたアレーから、CacheInvocationParameter.getValue() を使って、Object[]を生成する。

2.  Object[]をラップしたCacheKeyインスタンスを生成する。Arrays.deepHashCodeを使ってそのhashCodeを計算し、Arrays.deepEqualsを使って、他のキーとの比較を行う。

o  もし、CacheKeyGeneratorが例外を投げたら、その例外は、CacheKeyGeneratorの実行をトリガーしたアプリケーション・コードまで、伝搬されねばならない。

Page 171: Java EE7 䛸㻌JCache

Annotation Support Classes

o  CacheMethodDetails n  キャッシング・アノテーションを持つメソッドについての、Static

な情報。実行時に、CacheResolverFactory によって、 CacheResolver を決定する為に利用される。

o  CacheInvocationContext n  キャッシング・アノテーションを持つメソッドの実行についての実

行時の情報。CacheResolver によって、利用すべきキャッシュを決定するのに利用される。CacheMethodDetails を継承した、全てのstaticな情報が利用可能である。

Page 172: Java EE7 䛸㻌JCache

o  CacheKeyInvocationContext n  @CacheResult, @CachePut, @CacheRemoveEntryの

いずれかでアノテートされた、キー生成が行われるメソッドの実行に関する実行時の情報。CacheKeyGenerator によって、CacheKey を生成する為に利用される。CacheInvocationContext を継承した、全ての実行時あるいは、staticな情報が利用可能である。

o  CacheInvocationParameter n  メソッドの実行のパラメータについての実行時の情報。パラメ

ータ・アノテーション、その位置、型、値が含まれる。CacheInvocationContextとCacheKeyInvocationContextによって与えられる。

Page 173: Java EE7 䛸㻌JCache

o  CacheKey n  CacheKeyGeneratorインターフェースによって生成される。

CacheKey は、アノテーションによって相互作用する全てのキャッシュのキーとして利用される。全てのCacheKey は、複製不可でかつserializable出なければならない。

Page 174: Java EE7 䛸㻌JCache

Chapter 8 - Container and Provider Contracts for Deployment and Bootstrapping

Page 175: Java EE7 䛸㻌JCache

Container and Provider Contracts for Deployment and Bootstrapping

o  Java SEの環境では、 CacheManagerFactory.getCacheManagerメソッドは、新しいCacheManagerの生成を要求することがある。その為に、 javax.cache.CacheManager.CacheManagerFactoryProvider インターフェースのインスタンスを位置づける。

o  Java SEの環境で走るキャッシュ・プロバイダーの実装は、JARファイルの仕様で記述されたサービス・プロバイダの設定ファイルを備えた、サービス・プロバイダとしても動作すべきである。

Page 176: Java EE7 䛸㻌JCache

o  プロバイダーの設定ファイルは、プロバイダの実装クラスを、そのプロバイダをキャッシュ・マネージャのファクトリーとして位置づけて、CacheManagerFactory ブートストラップ・クラスに、エキスポートする役割をはたす。

o  The provider supplies the provider configuration file by creating a text file named javax.cache.spi.CacheManagerFactoryProvider and placing it in the META-INF/services directory of one of its JAR files. The contents of the file should be the name of the provider implementation class of the javax.cache.CacheManager.CacheManagerFactoryProvider interface.

Page 177: Java EE7 䛸㻌JCache

o  Example: o  A persistence vendor called ACME caching

products ships a JAR called acme.jar that contains its cache provider implementation. The JAR includes the provider configuration file. acme.jar

META-INF/services/javax.cache.spi.CacheManagerFactoryProvider com/acme/cache/CacheManagerFactoryProvider.class ...

Page 178: Java EE7 䛸㻌JCache

o  The contents of the META-INF/services/javax.cache.spi.CacheManagerFactoryProvider file is nothing more than the name of the implementation class: com.acme.cache.CacheManagerFactoryProvider

o  Cache provider jars may be installed or made available in the same ways as other service providers, e.g. as extensions or added to the application classpath according to the guidelines in the JAR File Specification.

Page 179: Java EE7 䛸㻌JCache

o  If more than one provider jar is registered the first one found by java.util.ServiceLoader will be used. If no provider is found, CacheManagerFactory.getCacheManager will thow an IllegalStateException.

Page 180: Java EE7 䛸㻌JCache

Use of Caching

o  The API provides a static means of accessing caching support through the class javax.class.Caching.

o  Examples include

// get the default cache manager CacheManager defaultCacheManager = Caching.getCacheManager(); // the default cache manager can also be fetched by name assert defaultCacheManager == Caching.getCacheManager(javax.cache.Caching.DEFAULT_CACHE_MANAGER_NAME); //Can get a non default named CacheManager CacheManager myCacheManager = Caching.getCacheManager("MyManager");

Page 181: Java EE7 䛸㻌JCache

Chapter 9 - Glossary

Page 182: Java EE7 䛸㻌JCache

o  CacheManager A container for caches, which holds references to them.

o  Cache A collection of related items. o  Caching Unit A logical grouping under the

control of a CacheManager o  Key A way of unambiguously identifying a

unique item in a Cache. o  Value The value stored in a Cache. Any Java

Object can be a value. o  CacheLoader A user-defined Class which is

used to load key/value pairs into a Cache on demand.

Page 183: Java EE7 䛸㻌JCache

o  CacheWriter A user-defined Class which is used to write key/value pairs into a cache after a put operation.

o  Cache Store A place where cache data is kept. Caches may have multiple stores.

o  CacheEventListener A user-defined Class which listens to Cache events.

o  Eviction Policy Method by which elements are evicted from the cache. E.g. FIFO, LFU, …

Page 184: Java EE7 䛸㻌JCache

Resin 4.0 jcache (distributed caching)

Page 185: Java EE7 䛸㻌JCache

public class MyServlet extends GenericServlet { @Current Cache _cache; public void service(ServletRequest req, ServletResponse res) { PrintWriter out = res.getWriter(); String data = (String) _cache.get("my-data"); if (data != null) { out.println("cached data: " + data); } else { data = generateComplicatedData(); _cache.put("my-data", data); out.println("new data: " + data); } } }

http://www.facebook.com/note.php?note_id=58113794812

Page 186: Java EE7 䛸㻌JCache

<web-app xmlns="http://caucho.com/ns/resin" xmlns:cluster="urn:java:com.caucho.cluster"> <cluster:ClusterCache name="comment-cache"/> </web-app>

Page 187: Java EE7 䛸㻌JCache

Maven Snippet

<dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> <version>0.3</version> </dependency>

Page 188: Java EE7 䛸㻌JCache

Creating a CacheManager CacheManager cacheManager = Caching.getCacheManager(); CacheManager cacheManager = Caching.getCacheManager(“app1”,       Thread.currentThread().getContextClassLoader()); CacheManager cacheManager = new RICacheManager(“app1”,       Thread.currentThread().getContextClassLoader()); String className = "javax.cache.implementation.RIServiceProvider"; Class<ServiceProvider> clazz       =(Class<ServiceProvider>)Class.forName(className); ServiceProvider provider = clazz.newInstance(); return provider.createCacheManager(Thread.currentThread(). getContextClassLoader(), "app1");

Page 189: Java EE7 䛸㻌JCache

o  We expect implementations to have their own well-known configuration files which will be used to configure the CacheManager.

o  The name of the CacheManager can be used to distinguish the configuration file.

o  For ehcache, this will be the familiar ehcache.xml placed at the root of the classpath with a hyphenated prefix for the name of the CacheManager. So, the default CacheManager will simply be ehcache.xml and “myCacheManager” will be app1-ehcache.xml.

Page 190: Java EE7 䛸㻌JCache

Creating a Cache cacheManager = getCacheManager(); CacheConfiguration cacheConfiguration =    cacheManager.createCacheConfiguration() cacheConfiguration.setReadThrough(true); Cache testCache =    cacheManager.createCacheBuilder(“testCache”)     .setCacheConfiguration(cacheConfiguration).build();

Page 191: Java EE7 䛸㻌JCache

Getting a reference to a Cache

o  You get caches from the CacheManager. To get a cache called “testCache”:

Cache<Integer, Date> cache =     cacheManager.getCache(“testCache”);

Page 192: Java EE7 䛸㻌JCache

Basic Cache Operations

o  To put to a cache: Cache<Integer, Date> cache =   cacheManager.getCache(cacheName); Date value1 = new Date(); Integer key = 1; cache.put(key, value1); o  To get from a cache: Cache<Integer, Date> cache = cacheManager.getCache(cacheName); Date value2 = cache.get(key);

Page 193: Java EE7 䛸㻌JCache

o  To remove from a cache:

Cache<Integer, Date> cache = cacheManager.getCache(cacheName); Integer key = 1; cache.remove(key);

Page 194: Java EE7 䛸㻌JCache

Annotations

o  The JSR107 annotations cover the most common cache operations including: n  @CacheResult – use the cache n  @CachePut – put into the cache n  @CacheRemoveEntry – remove a single entry from

the cache n  @CacheRemoveAll – remove all entries from the

cache

Page 195: Java EE7 䛸㻌JCache

public class DomainDao { @CachePut(cacheName="domainCache") public void updateDomain(String domainId, @CacheKeyParam int index, @CacheValue Domain domain) { ... } }

Page 196: Java EE7 䛸㻌JCache

Annotation Example

public class BlogManager { @CacheResult(cacheName="blogManager") public Blog getBlogEntry(String title) {...} @CacheRemoveEntry(cacheName="blogManager") public void removeBlogEntry(String title) {...} @CacheRemoveAll(cacheName="blogManager") public void removeAllBlogs() {...} @CachePut(cacheName=”blogManager”) public void createEntry(@CacheKeyParam String title, @CacheValue Blog blog) {...} @CacheResult(cacheName="blogManager") public Blog getEntryCached(String randomArg, @CacheKeyParam String title){...} }

Page 197: Java EE7 䛸㻌JCache

Wiring Up Spring

<jcache-spring:annotation-driven proxy-target-class="true"/> A full example is: <beans ...> <context:annotation-config/> <jcache-spring:annotation-driven proxy-target-class="true"/> <bean id="cacheManager" factory-method="getCacheManager" /> </beans>

Page 198: Java EE7 䛸㻌JCache

Wiring Up CDI o  First create an implementation of

javax.cache.annotation.BeanProvider and then tell CDI where to find it declaring a resource named javax.cache.annotation.BeanProvider in the classpath at /META-INF/services/.

o  For an example using the Weld implementation of CDI, see the CdiBeanProvider in our CDI test harness.

Page 199: Java EE7 䛸㻌JCache

Resin 4.0 jcache (distributed caching)

public class MyServlet extends GenericServlet { @Current Cache _cache; public void service(ServletRequest req, ServletResponse res) { PrintWriter out = res.getWriter(); String data = (String) _cache.get("my-data"); if (data != null) { out.println("cached data: " + data); } else { data = generateComplicatedData(); _cache.put("my-data", data); out.println("new data: " + data); } } }

Page 200: Java EE7 䛸㻌JCache

configuration

<web-app xmlns="http://caucho.com/ns/resin" xmlns:cluster="urn:java:com.caucho.cluster"> <cluster:ClusterCache name="comment-cache"/> </web-app>