Ehcache支持分层缓存的概念。
当想缓存堆内存以外的空间时,会发生下面的事情:
-
1.将数据添加到缓存意味着必须序列化key和value。
-
2.从缓存中读取数据意味着可能必须反序列化key和value。
单层设置
所有的单层选项都可以单独使用。例如,您可以将缓存包含仅在offheap中的数据。
以下可能性是有效配置:
-
堆
-
offheap
-
磁盘
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().offheap(2, MemoryUnit.GB)).build();
首先在配置构建器中定义键和值类型。然后指定要使用的资源(层)。这里我们只使用off-heap。
堆层
每个缓存的起点也越快,因为不需要序列化。按值传递键和值,默认值为by-reference。堆层可以通过条目或大小来确定大小。
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, EntryUnit.ENTRIES);
// or
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10);
// or
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, MemoryUnit.MB);
1.堆上只允许10个条目。
2.指定10个条目的数据。
3.只允许10 MB。
堆外层
如果希望使用堆外,则必须定义资源池,并提供要分配的内存大小。
ResourcePoolsBuilder.newResourcePoolsBuilder().offheap(10, MemoryUnit.MB);
请记住,堆外存储的数据必须被序列化和反序列化 - 因此比堆慢。因此,您应该支持大量数据的堆外堆,其中堆上会对垃圾收集产生太严重的影响。
磁盘层
对于磁盘层,数据存储在磁盘上。磁盘越快,越专用,访问数据的速度就越快。
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.with(CacheManagerBuilder.persistence(new File(getStoragePath(), "myData")))
.withCache("persistent-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.MB, true))
)
.build(true);
persistentCacheManager.close();
1.获得一个PersistentCacheManager
2.提供应存储数据的位置。
3.定义将由缓存使用的磁盘的资源池。第三个参数是一个布尔值,用于设置磁盘池是否持久。设置为true时,池是持久的。使用具有2个参数的版本时disk(long, MemoryUnit),池不是持久的。
持久性意味着缓存将在JVM重启后继续存在。重新启动JVM并CacheManager在同一位置创建磁盘持久性后,缓存中的所有内容仍然存在。无法在缓存管理器之间共享磁盘层。持久性目录当时专用于一个缓存管理器。
存储在磁盘上的数据必须被序列化/反序列化并写入磁盘/从磁盘读取 - 因此比堆和远程更慢。
多层设置
Ehcache要求堆层的大小小于offheap层的大小,并且offheap层的大小要小于磁盘层的大小。虽然Ehcache无法在配置时验证堆的基于计数的大小调整是否小于另一层的基于字节的大小调整,但您应该确保在测试期间就是这种情况。
考虑到上述因素,以下可能性是有效的配置:
堆+ offheap
堆+ offheap +磁盘
堆+ offheap +集群
堆+磁盘
堆+聚集
资源池
让我们重温前面使用的一个例子:
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.with(CacheManagerBuilder.persistence(new File(getStoragePath(), "myData")))
.withCache("threeTieredCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(10, EntryUnit.ENTRIES)
.offheap(1, MemoryUnit.MB)
.disk(20, MemoryUnit.MB, true)
)
).build(true);
这是一个使用3层(堆、堆外、磁盘)的缓存。它们是使用ResourcePoolsBuilder创建和链接的。声明顺序无关紧要(例如可以在堆前声明offheap),因为每一层都有一个高度。层的高度越高,层就越接近客户端。
理解资源池只是指定配置是非常重要的。它不是一个可以在缓存之间共享的池。例如,考虑以下代码:
ResourcePools pool = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10).build();
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("test-cache1", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, pool))
.withCache("test-cache2", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, pool))
.build(true);
您将得到两个缓存,每个缓存可以包含10个条目。不是10个条目的共享池。池永远不会在缓存之间共享。例外情况是集群缓存,可以共享或专用。