3. はじめに
o プレゼンの前半で、同じキャッシュというくくりで、CPUと
メモリーの間に置かれている、キャッシュの問題について
Cliff Clickの議論の紹介をした。もっとも、これは、キャ
ッシュが有効に機能していないという例なのだが。
o また、CPUのMulti-core化が、キャッシュにとってどうい
う意味を持つかを考えてみた。意外と複雑で、残念な
がら、すっきりした見通しは持てなかった。
o 現在のJCacheの仕様には、分散キャッシュの実装、あ
るいは、そのインターフェースの利用について、明示的
な言及は無い。昨年、立ち上がった、JSR 347: Data
Grids for the JavaTM Platform が、その一つの答
えだと思うのだが、今後の進展を注目している。
4. 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
5. 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
から
53. 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.
54. 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.
55. Object Caching for Java
Functional Specification for Object
Caching Service for Java (OCS4J), 2.0
http://jcp.org/aboutJava/communityprocess/jsr/
cacheFS.pdf
63. 値の設定と取得
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);
77. 目標
o Object Cache:
このAPIは、Javaオブジェクトをキャッシュする。
o Support for By-Value caching and
optionally, By-Reference.
後者の参照はヒープの中に、前者では、キーと値は、
両方とも、値に変換される。
o Support for Flexible Implementations
仕様は、プロセスでの実装と、分散での実装の両方を
サポートする。
118. トランザクション・サンプル
//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();
130. //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();
133. //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();
141. 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.
142. 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.
149. o 次の例は、このクラスのキャッシュのデフォールトとして
利用される、”cities”という名前のキャッシュを指定して
いる。
o getCityメソッドの、@CacheResultアノテーションは、
実行時にこのキャッシュの名前を利用する。
@CacheDefaults(cacheName=”cities”)
public class CitySource {
@CacheResult
public City getCity(int lat, int lon) {
//...
}
}
150. 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() {
...
}
}
158. package my.app;
public class DomainDao {
@CacheRemoveEntry(cacheName="domainCache")
public void deleteDomain(String domainId, int index) {
...
}
}
174. Chapter 8 - Container and
Provider Contracts for Deployment
and Bootstrapping
175. Container and Provider Contracts for
Deployment and Bootstrapping
o Java SEの環境では、
CacheManagerFactory.getCacheManagerメソッ
ドは、新しいCacheManagerの生成を要求することが
ある。その為に、
javax.cache.CacheManager.CacheManagerFact
oryProvider インターフェースのインスタンスを位置づ
ける。
o Java SEの環境で走るキャッシュ・プロバイダーの実
装は、JARファイルの仕様で記述されたサービス・プロ
バイダの設定ファイルを備えた、サービス・プロバイダと
しても動作すべきである。
176. 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.CacheManagerFact
oryProvider interface.
177. 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
...
178. 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.
179. 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.
180. 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_M
ANAGER_NAME);
//Can get a non default named CacheManager
CacheManager myCacheManager =
Caching.getCacheManager("MyManager");
182. 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.
183. 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, …
189. 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.
191. 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”);
192. 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);
193. o To remove from a cache:
Cache<Integer, Date> cache =
cacheManager.getCache(cacheName);
Integer key = 1;
cache.remove(key);
194. 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
195. public class DomainDao {
@CachePut(cacheName="domainCache")
public void updateDomain(String domainId,
@CacheKeyParam int index,
@CacheValue Domain domain) {
...
}
}
196. 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){...}
}
197. 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>
198. 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.
199. 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);
}
}
}