Ehcache存储策略总结
如何使用
?導包:
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache --> <dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.9.4</version> </dependency>使用 :
// 第一步 創建cache manager CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withCache("preConfigured",CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))) .build(); cacheManager.init(); //第二步 創建cache Cache<Long, String> preConfigured =cacheManager.getCache("preConfigured", Long.class, String.class); Cache<Long, String> myCache = cacheManager.createCache("myCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))); //第三步 使用 myCache.put(1L, "da one!"); String value = myCache.get(1L); cacheManager.removeCache("preConfigured"); //第四步 關閉cache cacheManager.close();?build cacheManager時也同時創建了一個名為 "preConfigured"的cache,也可以在cacheManager創建完后再創建cache,比如后面的“myCache"。之后使用就如同使用普通的map一樣。 但非常關鍵的一點,如果cache不再用了,要記得刪掉,cacheManager也要及得及時close掉,否則容易導致內存泄露。
?
在createCache時,需要指定3個參數,分別是cache里key value的class,和一份存儲配置ResourcePools。 這是因為ehcache支持多級存儲(這也是它最大的特性),你可以配置部分數據優先存儲在堆內,存不下就存堆外,再存不下可以存在磁盤。 所以它需要知道key和value的class,用來對K-V做序列化和反序列化,方便多層級之間數據傳輸。 因為存在對象的序列化和反序列化,你就不得不考慮下性能問題,因為序列化和反序列化都是需要時間的。但所幸的是有個局部性法則讓你不用太多擔心。ehcache里默認cache策略是LRU,它優先把數據優先存堆(heap)里的,內存中存不下以及被LUR淘汰下來的數據會被ehcache序列化后存入堆外或者磁盤。LRU策略會逐步把低頻使用的數據往下層存儲淘汰,從而保證高頻數據盡可能都在上層存儲中。 像上面ehcahe這種多層級的設計,可以再盡可能少的影響性能的情況下減少堆內內存的使用,也可以減少內存的使用。 但有個可能的風險點,java語言本身其實是不太希望用戶使用堆外的空間的,因為堆外空間脫離的JVM的控制,JVM無法對其做GC,可能會有內存泄露的風險。ehcache不得不讓用戶去考慮內存空間釋放的問題,雖然很簡單調用下removeCahce()和close()就行,但依舊有內存泄露的風險。
?
多級存儲
上面已經提到了Ehcache的多級存儲,共支持4個級別的存儲。 1. 堆 2. 堆外 3. 磁盤 4. 集群 如果分別使用上面四中存儲,Ehcache提供一個個CacheConfigurationBuilder來創建相關配置。
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder().offheap(2, MemoryUnit.GB)).build(); // 1 ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, EntryUnit.ENTRIES); // 2 // or ResourcePoolsBuilder.heap(10); // or ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, MemoryUnit.MB);可以使用CacheConfigurationBuilder來創建cache配置,分別用heap() 和offheap()來指定堆存儲和堆外存儲配置,這兩個方法都支持指定存儲實例數或者存儲空間的大小。上面代碼中1指定最大存儲2gb,2表最多存儲10個實例,超過了就會用默認的LRU策略往下層淘汰。 如果要使用磁盤存儲,在cache創建是需要先指定存儲的路徑和文件名,使用示例如下
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();集群存儲方式配置參考文檔cluster cache 這些存儲策略可以隨意組合,比如以下的使用方式都是支持的。
- 堆 + 堆外
- 堆 + 堆外 + 磁盤
- 堆 + 堆外 + 集群
- 堆 + 磁盤 - 堆 + 集群
更多資料可以參考官方文檔
?
?
?
總結
以上是生活随笔為你收集整理的Ehcache存储策略总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: es创建索引库,无法使用InetSock
- 下一篇: java异步执行任务