官网链接:https://www.ehcache.org/
官网英文文档链接:https://www.ehcache.org/documentation/3.8/getting-started.html
Maven 依赖:
<dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.8.1</version></dependency>
Ehcache 3 API 用法:
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() //1.withCache("preConfigured",CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))) //2.build(); //3
cacheManager.init(); //4Cache<Long, String> preConfigured =cacheManager.getCache("preConfigured", Long.class, String.class); //5Cache<Long, String> myCache = cacheManager.createCache("myCache", //6CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));myCache.put(1L, "da one!"); //7
String value = myCache.get(1L); //8cacheManager.removeCache("preConfigured"); //9cacheManager.close(); //10
- 静态方法org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder返回一个新的org.ehcache.config.builders.CacheManagerBuilder实例。
- 用builder来定义一个别名为"preConfigured"的Cache。调用cacheManager.build()时会创建该cache。withCache()方法的第一个参数是cache别名,用来以后取缓存用。第二个参数用来配置Cache,我们用静态方法newCacheConfigurationBuilder()来创建默认的配置。
- 调用build会返回一个已经实例化但还没有初始化的CacheManager。
- 使用CacheManager前需要先初始化。有两种方法可以进行初始化:调用CacheManager.init()或者调用CacheManagerBuilder.build(boolean init)。
- 为了从CacheManager获得一个cache,我们需要传递alias, key type和value type。例如,在第二步中,传递alias="preConfigured",keyType=Long.class,valueType=String.class。如果type不匹配,CacheManager会抛出ClassCastException。这样可以保护Cache不被随机的type污染。
- 实例化并初始化的Cache可以通过CacheManager.getCache来获取。
- 新建的Cache现在可以用来存储元素了。第一个参数是key,第二个是value,key和value的type必须和CacheConfiguration中定义的一直。
- 调用cache.get(key)可以获得值。如果没有值则会返回null。
- 调用CacheManager.removeCache(String)可以删除Cache。CacheManager不仅会删除Cache的reference,同时会关闭Cache。
- CacheManager.close()会关闭所有的Cache实例。
XML configuration配置文件
你可以创建一个XML文件来配置CacheManager。
<configxmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns='http://www.ehcache.org/v3'xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd"><cache alias="foo"> //1<key-type>java.lang.String</key-type> //2<value-type>java.lang.String</value-type> //2<resources><heap unit="entries">20</heap> //3<offheap unit="MB">10</offheap> //4</resources></cache><cache-template name="myDefaults"> //5<key-type>java.lang.Long</key-type><value-type>java.lang.String</value-type><heap unit="entries">200</heap></cache-template><cache alias="bar" uses-template="myDefaults"> //6<key-type>java.lang.Number</key-type></cache><cache alias="simpleCache" uses-template="myDefaults" /> //7</config>
- 给Cache别名为foo。
- foo的key,value的type定义为String;如果没有特别定义,默认是java.lang.Object。
- foo最多在堆中有2000个entry。
- 最多500MB的堆外内存。
- <cache-template>可以让你创建一个abstract配置并以后extend它。
- 命名为bar的缓存用到了命名为myDefaults的<cache-template>并override它的key-type到java.lang.Number。
- 命名为simpleCache的缓存用myDefaults来作为它的缓存配置。
为了解析一个XML配置,你可以用XmlConfiguration:
URL myUrl = getClass().getResource("/my-config.xml"); //1
Configuration xmlConfig = new XmlConfiguration(myUrl); //2
CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig); //3
- 添加XML路径。
- 实例化XMLConfiguration。
- 用静态方法org.ehcache.config.builders.CacheManagerBuilder.newCacheManager(org.ehcache.config.Configuration)创建CacheManager实例。
集群方案下创建cache manager
为了支持Terracotta集群方案,需要先启动start the Terracotta server。此外,为了创建集群方案的cache manager,亦需要提供集群服务的配置:
CacheManagerBuilder<PersistentCacheManager> clusteredCacheManagerBuilder =CacheManagerBuilder.newCacheManagerBuilder() .with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application")) .autoCreate(c -> c));
PersistentCacheManager cacheManager = clusteredCacheManagerBuilder.build(true); cacheManager.close();
- 返回org.ehcache.config.builders.CacheManagerBuilder实例。
- 用静态方法ClusteringServiceConfigurationBuilder.cluster(URI)来连接对应URI的集群。例子中的URI指向identifier为my-application的集群(默认端口号9410);auto-create会在server中的集群不存在时创建。
- 返回一个完全初始化的cache manager。
- 集群没有时会自动创建。
- 关闭cache manager。
Storage Tiers存储层级
Ehcache可以在数据越来越大时,存储到相对较慢的层级中。
因为快速的存储资源相对稀有,所以hottest的资源会存在这里。因此那些较少用到的data会被移动到较慢但存储容量更大的层级中。更频繁用到的数据会移动到更快的层级中。
经典的3层级带硬盘存储的方案:
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(new File(getStoragePath(), "myData"))) //1.withCache("threeTieredCache",CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, EntryUnit.ENTRIES) //2.offheap(1, MemoryUnit.MB) //3.disk(20, MemoryUnit.MB, true) //4 )).build(true);Cache<Long, String> threeTieredCache = persistentCacheManager.getCache("threeTieredCache", Long.class, String.class);
threeTieredCache.put(1L, "stillAvailableAfterRestart"); //5persistentCacheManager.close();
- 如果你希望使用硬盘存储,你要提供一个path给CacheManagerBuilder.persistence()方法。
- 给堆定义一个资源池。这是一个较快但是较小的池。
- 给堆外内存定义一个资源池。这是一个较快单大一点的池。
- 给硬盘定义一个持久化的资源池。
- 所有存在cache中的值都可以在JVM重启后获得。
Data freshness缓存失效
缓存失效通过Expiry控制。下面这个例子展示了如果控制缓存失效:
CacheConfiguration<Long, String> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,ResourcePoolsBuilder.heap(100)) //1.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(20))) //2.build();
- Expiry在定义cache confuguration的时候配置的。
- 通过Duration配置time-to-live失效时间。