java ehcache lru_玩转EhCache之最简单的缓存框架

一、简介

Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统。Ehcache 从 Hibernate 发展而来,逐渐涵盖了 Cahce 界的全部功能,是目前发展势头最好的一个项目。具有快速,简单,低消耗,依赖性小,扩展性强,支持对象或序列化缓存,支持缓存或元素的失效,提供 LRU、LFU 和 FIFO 缓存策略,支持内存缓存和磁盘缓存,分布式缓存机制等等特点。

备注:为了方便大家了最新版本的Ehcache,本文中1-6节采用的最新的Ehcache3.0的特性和使用介绍,从第7节开始采用的是Ehcache2.10.2版本来与Spring相结合来做案例介绍,包括后面的源码分析也将采用这个版本

二、主要特性

快速;

简单;

多种缓存策略;

缓存数据有两级:内存和磁盘,因此无需担心容量问题;

缓存数据会在虚拟机重启的过程中写入磁盘;

可以通过 RMI、可插入 API 等方式进行分布式缓存;

具有缓存和缓存管理器的侦听接口;

支持多缓存管理器实例,以及一个实例的多个缓存区域;

提供 Hibernate 的缓存实现;

三、Ehcache的架构设计图

5a0669d6305e

说明

CacheManager:是缓存管理器,可以通过单例或者多例的方式创建,也是Ehcache的入口类。

Cache:每个CacheManager可以管理多个Cache,每个Cache可以采用hash的方式管理多个Element。

Element:用于存放真正缓存内容的。

结构图如下所示:

5a0669d6305e

四、Ehcache的缓存数据淘汰策略

FIFO:先进先出

LFU:最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。

LRU:最近最少使用,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

五、Ehcache的缓存数据过期策略

Ehcache采用的是懒淘汰机制,每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期。

六、Ehcache缓存的使用介绍

6.1、目前最新的Ehcache是3.0版本,我们也就使用3.0版本来介绍它的使用介绍,看如下代码:

5a0669d6305e

Paste_Image.png

注:这段代码介绍了Ehcache3.0的缓存使用生命周期的一个过程。

1、静态方法CacheManagerBuilder.newCacheManagerBuilder将返回一个新的org.ehcache.config.builders.CacheManagerBuilder的实例。

2、当我们要构建一个缓存管理器的时候,使用CacheManagerBuilder来创建一个预配置(pre-configured)缓存。

第一个参数是一个别名,用于Cache和Cachemanager进行配合。

第二个参数是org.ehcache.config.CacheConfiguration主要用来配置Cache。我们使用org.ehcache.config.builders.CacheConfigurationBuilder的静态方法newCacheConfigurationBuilder来创建一个默认配置实例。

3、最后调用.build方法返回一个完整的实例,当然我们也能使用CacheManager来初始化。

4、在你开始使用CacheManager的时候,需要使用init()方法进行初始化。

5、我们能取回在第二步中设定的pre-configured别名,我们对于key和要传递的值类型,要求是类型安全的,否则将抛出ClassCastException异常。

6、可以根据需求,通过CacheManager创建出新的Cache。实例化和完整实例化的Cache将通过CacheManager.getCache API返回。

7、使用put方法存储数据。

8、使用get方法获取数据。

9、我们可以通过CacheManager.removeCache方法来获取Cache,但是Cache取出来以后CacheManager将会删除自身保存的Cache实例。

10、close方法将释放CacheManager所管理的缓存资源。

6.2、关于磁盘持久化

5a0669d6305e

Paste_Image.png

注:如果您想使用持久化机制,就需要提供一个磁盘存储的位置给CacheManagerBuilder.persistence这个方法,另外在使用的过程中,你还需要定义一个磁盘使用的资源池。

上面的例子其实是分配了非常少的磁盘存储量,不过我们需要注意的是由于存储在磁盘上我们需要做序列化和反序列化,以及读和写的操作。它的速度肯定比内存要慢的多。

6.3、通过xml配置文件创建CacheManager

5a0669d6305e

Paste_Image.png

注:

1、描述缓存的别名。

2、foo的key的类型指定为String类型,而value并没有指定类型,默认就是Object类型。

3、可以在堆中为foo创建2000个实体。

4、在开始淘汰过期缓存项之前,可以分配多达500M的堆内存。

5、cache-template可以实现一个配置抽象,以便在未来可以进行扩展。

6、bar使用了cache-template模板myDefaults,并且覆盖了key-type类型,myDefaults的key-type是Long类型,覆盖后成了Number类型。

使用以下代码创建CacheManager:

5a0669d6305e

Paste_Image.png

七、UserManagerCache介绍

** 7.1 什么是UserManagerCache,它能做什么?**

UserManagerCache这是在Ehcache3.0中引入的新的概念,它将直接创建缓存而不需要使用CacheManager来进行管理。所以这也就是UserManagerCache名称的由来。

由于没有CacheManager的管理,用户就必须要手动配置所需要的服务,当然如果你发现要使用大量的服务,那么CacheManager则是更好的选择。

** 7.2 使用示例**

1、基本示例

UserManagedCache userManagedCache =

UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)

.build(false);

userManagedCache.init();

userManagedCache.put(1L, "da one!");

userManagedCache.close();

2、持久化示例

LocalPersistenceService persistenceService = new DefaultLocalPersistenceService(new DefaultPersistenceConfiguration(new File(getStoragePath(), "myUserData")));

PersistentUserManagedCache cache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)

.with(new UserManagedPersistenceContext("cache-name", persistenceService))

.withResourcePools(ResourcePoolsBuilder.newResourcePoolsBuilder()

.heap(10L, EntryUnit.ENTRIES)

.disk(10L, MemoryUnit.MB, true))

.build(true);

// Work with the cache

cache.put(42L, "The Answer!");

assertThat(cache.get(42L), is("The Answer!"));

cache.close();

cache.destroy();

3、读写缓存示例

UserManagedCache cache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)

.withLoaderWriter(new SampleLoaderWriter())

.build(true);

// Work with the cache

cache.put(42L, "The Answer!");

assertThat(cache.get(42L), is("The Answer!"));

cache.close();

注:

如果你希望频繁的读和写缓存,则可以使用CacheLoaderWriter。

4、缓存淘汰策略示例

UserManagedCache cache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)

.withEvictionAdvisor(new OddKeysEvictionAdvisor())

.withResourcePools(ResourcePoolsBuilder.newResourcePoolsBuilder()

.heap(2L, EntryUnit.ENTRIES))

.build(true);

// Work with the cache

cache.put(42L, "The Answer!");

cache.put(41L, "The wrong Answer!");

cache.put(39L, "The other wrong Answer!");

cache.close();

注:

如果你想使用缓存淘汰算法来淘汰数据,则要使用EvictionAdvisor这个类。

5、按字节设定的缓存示例

UserManagedCache cache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class)

.withSizeOfMaxObjectSize(500, MemoryUnit.B)

.withSizeOfMaxObjectGraph(1000)

.withResourcePools(ResourcePoolsBuilder.newResourcePoolsBuilder()

.heap(3, MemoryUnit.MB))

.build(true);

cache.put(1L, "Put");

cache.put(1L, "Update");

assertThat(cache.get(1L), is("Update"));

cache.close();

注:

withSizeOfMaxObjectGraph这个主要是调整可以设置多少字节对象。

.heap方法主要是设置每个对象最大可以设置多大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值