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個條目的共享池。池永遠不會在緩存之間共享。例外情況是叢集緩存,可以共享或專用。