Ehcache教程

    <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(); //4
 
Cache<Long, String> preConfigured =
    cacheManager.getCache("preConfigured", Long.class, String.class); //5
 
Cache<Long, String> myCache = cacheManager.createCache("myCache", //6
    CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));
 
myCache.put(1L, "da one!"); //7
String value = myCache.get(1L); //8
 
cacheManager.removeCache("preConfigured"); //9
 
cacheManager.close(); //10
  1. 静态方法org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder返回一个新的org.ehcache.config.builders.CacheManagerBuilder实例。
  2. 用builder来定义一个别名为"preConfigured"的Cache。调用cacheManager.build()时会创建该cache。withCache()方法的第一个参数是cache别名,用来以后取缓存用。第二个参数用来配置Cache,我们用静态方法newCacheConfigurationBuilder()来创建默认的配置。
  3. 调用build会返回一个已经实例化但还没有初始化的CacheManager。
  4. 使用CacheManager前需要先初始化。有两种方法可以进行初始化:调用CacheManager.init()或者调用CacheManagerBuilder.build(boolean init)。
  5. 为了从CacheManager获得一个cache,我们需要传递alias, key type和value type。例如,在第二步中,传递alias="preConfigured",keyType=Long.class,valueType=String.class。如果type不匹配,CacheManager会抛出ClassCastException。这样可以保护Cache不被随机的type污染。
  6. 实例化并初始化的Cache可以通过CacheManager.getCache来获取。
  7. 新建的Cache现在可以用来存储元素了。第一个参数是key,第二个是value,key和value的type必须和CacheConfiguration中定义的一直。
  8. 调用cache.get(key)可以获得值。如果没有值则会返回null。
  9. 调用CacheManager.removeCache(String)可以删除Cache。CacheManager不仅会删除Cache的reference,同时会关闭Cache。
  10. CacheManager.close()会关闭所有的Cache实例。

XML configuration配置文件

你可以创建一个XML文件来配置CacheManager。

<config
    xmlns: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>
  1. 给Cache别名为foo。
  2. foo的key,value的type定义为String;如果没有特别定义,默认是java.lang.Object。
  3. foo最多在堆中有2000个entry。
  4. 最多500MB的堆外内存。
  5. <cache-template>可以让你创建一个abstract配置并以后extend它。
  6. 命名为bar的缓存用到了命名为myDefaults的<cache-template>并override它的key-type到java.lang.Number。
  7. 命名为simpleCache的缓存用myDefaults来作为它的缓存配置。

为了解析一个XML配置,你可以用XmlConfiguration:

<config
    xmlns: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>
  1. 添加XML路径。
  2. 实例化XMLConfiguration。
  3. 用静态方法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(); 
  1. 返回org.ehcache.config.builders.CacheManagerBuilder实例。
  2. 用静态方法ClusteringServiceConfigurationBuilder.cluster(URI)来连接对应URI的集群。例子中的URI指向identifier为my-application的集群(默认端口号9410);auto-create会在server中的集群不存在时创建。
  3. 返回一个完全初始化的cache manager。
  4. 集群没有时会自动创建。
  5. 关闭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"); //5
 
persistentCacheManager.close();
  1. 如果你希望使用硬盘存储,你要提供一个path给CacheManagerBuilder.persistence()方法。
  2. 给堆定义一个资源池。这是一个较快但是较小的池。
  3. 给堆外内存定义一个资源池。这是一个较快单大一点的池。
  4. 给硬盘定义一个持久化的资源池。
  5. 所有存在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();
  1. Expiry在定义cache confuguration的时候配置的。
  2. 通过Duration配置time-to-live失效时间。
参考资料: 1、https://blog.csdn.net/weixin_42504835/article/details/108791319 【20220111】
上一篇:自定义缓存-ehcache


下一篇:数字图像与机器视觉基础补充(补)