Ehcache 是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大,最初知道它,是从hibernate的缓存开始的。Ehcache 3.2为现在官方最新版;
这个新的主要版本的Ehcache提供以下
- 修改缓存API,利用Java泛型和简化了交互,
- 全面兼容javax。 缓存API(jsr - 107),
- Offheap存储功能,包括Offheap只缓存,
- Ehcache 2.倍提高性能,
- 开箱即用的春天由于javax缓存集成。 缓存的支持,
缓存管理
与之前版本相比,3.0之后主要是通过
CacheManager
我们先从基础实例来讲解一下
- import org.ehcache.Cache;
- import org.ehcache.CacheManager;
- import org.ehcache.config.builders.CacheConfigurationBuilder;
- import org.ehcache.config.builders.CacheManagerBuilder;
- import org.ehcache.config.builders.ResourcePoolsBuilder;
-
-
-
-
-
-
-
-
-
-
-
- public class Test {
- public static void main(String[] args) {
- CacheManager cacheManager = CacheManagerBuilder
- .newCacheManagerBuilder()
- .withCache(
- "preConfigured",
- CacheConfigurationBuilder.newCacheConfigurationBuilder(
- Long.class, String.class,
- ResourcePoolsBuilder.heap(100)).build())
- .build(true);
-
- 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(100)).build());
-
- preConfigured.put(2L, "hello Ehcache");
- String value1=preConfigured.get(2L);
- System.out.println(value1);
- myCache.put(1L, "da one!");
- String value = myCache.get(1L);
- System.out.println(value);
- cacheManager.close();
-
- }
- }
1.静态方法
org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder
返回一个新的
org.ehcache.config.builders.CacheManagerBuilder
2.当我们使用builder来注册一个预先配置好的Cache,当我们调用
.build() 时,实际上是一个已经创建好的CacheManager。第一个参数string是用于给Cache取一个别名,第二个参数
org.ehcache.config.CacheConfiguration
配置
Cache
。 我们使用静态
.newCacheConfigurationBuilder()
方法
org.ehcache.config.builders.CacheConfigurationBuilder
创建一个默认的配置;
3.
最后,调用
.build()
返回一个完全实例化,但未初始化的
CacheManager
供我们使用
4.在我们开始使用CacheManager是,我们需要通过init()builder来初始化它,可以通过布尔值来觉得是否build(boolean);
5.现在开始声明一个Cache,并将他的句柄声明为preConfigured,通过cacheManager的get方法,输入别名得到我们预先声明的Cache;
6.我们可以根据需要创建一个新的Cache,他跟步骤2一样,传入一个别名myCache并进行初始化;
7.接着装载我们的Cache值,并成功的打印出我们的hello Ehcache;
用户管理缓存
用户管理缓存是一个新的概念引入Ehcache 3。 它提供了创建缓存的能力不是由一个管理CacheManager
。 因此的名字用户管理缓存。
- public class UserManaged {
-
- public static void main(String[] args) {
- UserManagedCache<Long, String> userManagedCache =
- UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)
- .build(false);
- userManagedCache.init();
- userManagedCache.put(1L, "hello UserManagedCache!");
- System.out.println(userManagedCache.get(1L));
- userManagedCache.close();
- }
-
- }
这个功能的目的是满足缓存使用情况的复杂性增加缓存管理器没有附加值。 观点是:本地缓存方法,线程本地缓存缓存的生命周期或其他任何地方比应用程序生命周期较短。
限制
因为不再是一个缓存管理器提供的服务,用户管理缓存的主要限制是用户手工配置所需的所有服务。 当然,如果你发现自己需要大量的服务,也许缓存管理器是一个更好的选择!
API扩展
而一个UserManagedCache
扩展Cache
,它提供了额外的方法:
查看UserManagedCache源码我们可以看到
- package org.ehcache;
-
-
-
-
-
-
-
-
-
-
- public interface UserManagedCache<K, V> extends Cache<K, V> {
-
-
-
-
-
-
-
-
-
-
-
- void init() throws StateTransitionException;
-
-
-
-
-
-
-
-
-
-
-
-
-
- void close() throws StateTransitionException;
-
-
-
-
-
-
- Status getStatus();
-
- }
我们可以看到,这些方法需要明确的去处理缓存的生命周期;
- package org.ehcache;
-
-
-
-
-
-
-
- public interface PersistentUserManagedCache<K, V> extends UserManagedCache<K, V> {
-
-
-
-
-
-
-
- void destroy() throws CachePersistenceException;
- }
同时使用CacheManager是不会影响
UserManagedCache缓存的
- public static void persistent() {
-
- LocalPersistenceService persistenceService = new DefaultLocalPersistenceService(
- new DefaultPersistenceConfiguration(new File("C:/Ehcache", "myUserData")));
-
- PersistentUserManagedCache<Long, String> cache = UserManagedCacheBuilder
- .newUserManagedCacheBuilder(Long.class, String.class)
- .with(new UserManagedPersistenceContext<Long, String>(
- "cache-name", persistenceService))
-
- .withResourcePools(
- ResourcePoolsBuilder.newResourcePoolsBuilder()
- .heap(10L, EntryUnit.ENTRIES)
- .disk(10L, MemoryUnit.MB, true)).build(true);
-
-
- cache.put(42L, "The Answer!");
- System.out.println(cache.get(42L));
-
- cache.close();
- try {
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
如果我们不去显示的去销毁缓存数据的话,会在我们的磁盘里产生一些数据;
存储层
Ehcache 3,在以前的版本中,提供了一种分层模型,允许存储越来越多的数据在低速层 (通常更丰富)。
这个想法就是资源与更快的存储更罕见,但在“热门”数据是首选。 因此将不常用的数据层搬到更丰富但速度较慢。 温度数据断裂 层越快。
存储方式:
1、堆内存储:速度快,但是容量有限。
2、堆外(OffHeapStore)存储:被称为BigMemory,只在企业版本的Ehcache中提供,原理是利用nio的DirectByteBuffers实现,比存储到磁盘上快,而且完全不受GC的影响,可以保证响应时间的稳定性;但是direct buffer的在分配上的开销要比heap buffer大,而且要求必须以字节数组方式存储,因此对象必须在存储过程中进行序列化,读取则进行反序列化操作,它的速度大约比堆内存储慢一个数量级。
(注:direct buffer不受GC影响,但是direct buffer归属的的Java对象是在堆上且能够被GC回收的,一旦它被回收,JVM将释放direct buffer的堆外空间。)
3、磁盘存储。
堆外:
- public static void offHeap(){
- CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().withCache("tieredCache",
- CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
- ResourcePoolsBuilder.newResourcePoolsBuilder()
- .heap(10, EntryUnit.ENTRIES)
- .offheap(10, MemoryUnit.MB))
- )
- .build(true);
-
- cacheManager.close();
- }
上面的例子分配少量的堆外。 记住,存储的数据堆必须序列化和反序列化,因此比堆慢。 因此你应该忙堆大量数据,堆也会严重影响垃圾收集。
不要忘记定义在java选项-XX:MaxDirectMemorySize
磁盘的持久性
- public static void lasting(){
- PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
- .with(CacheManagerBuilder.persistence("url"+ File.separator + "myData"))
- .withCache("persistent-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
- ResourcePoolsBuilder.newResourcePoolsBuilder()
- .heap(10, EntryUnit.ENTRIES)
- .disk(10, MemoryUnit.MB, true))
- )
- .build(true);
-
- persistentCacheManager.close();
- }
上面的例子分配少量的磁盘存储。 记住,数据存储在磁盘上必须序列化/反序列化和/从磁盘读-写的 因此比堆和offheap慢。 你应该为大量数据支持磁盘。
使用磁盘存储的另一个原因是跨应用程序重启持久性。 注意,Ehcache 3只提供持久性的干净的关闭。
Byte-sized堆
字节大小的运行时性能的影响取决于大小和图的复杂性数据缓存。
- public static void heap() {
- CacheConfiguration<Long, String> usesConfiguredInCacheConfig = CacheConfigurationBuilder
- .newCacheConfigurationBuilder(
- Long.class,
- String.class,
- ResourcePoolsBuilder.newResourcePoolsBuilder()
- .heap(10, MemoryUnit.KB)
- .offheap(10, MemoryUnit.MB))
- .withSizeOfMaxObjectGraph(1000)
- .withSizeOfMaxObjectSize(1000, MemoryUnit.B).build();
-
- CacheConfiguration<Long, String> usesDefaultSizeOfEngineConfig = CacheConfigurationBuilder
- .newCacheConfigurationBuilder(
- Long.class,
- String.class,
- ResourcePoolsBuilder.newResourcePoolsBuilder()
- .heap(10, MemoryUnit.KB)
- .offheap(10, MemoryUnit.MB)).build();
-
- CacheManager cacheManager = CacheManagerBuilder
- .newCacheManagerBuilder()
- .withDefaultSizeOfMaxObjectSize(500, MemoryUnit.B)
-
- .withDefaultSizeOfMaxObjectGraph(2000)
- .withCache("usesConfiguredInCache", usesConfiguredInCacheConfig)
- .withCache("usesDefaultSizeOfEngine",
- usesDefaultSizeOfEngineConfig).build(true);
-
- Cache<Long, String> usesConfiguredInCache = cacheManager.getCache(
- "usesConfiguredInCache", Long.class, String.class);
-
- usesConfiguredInCache.put(1L, "one");
- System.out.println(usesConfiguredInCache.get(1L));
-
- Cache<Long, String> usesDefaultSizeOfEngine = cacheManager.getCache(
- "usesDefaultSizeOfEngine", Long.class, String.class);
-
- usesDefaultSizeOfEngine.put(1L, "one");
- System.out.println(usesDefaultSizeOfEngine.get(1L));
-
- cacheManager.close();
- }