EhCache 配置注解及使用介绍
了解 Ehcache
Ehcache 在很多项目中都出现过,用法也比较简单。一般的加些配置就可以了,而且 Ehcache 可以对页面、对象、数据进行缓存,同时支持集群/分布式缓存。如果整合 Spring、Hibernate 也非常的简单,Spring 对Ehcache 的支持也非常好。EHCache 支持内存和磁盘的缓存,支持 LRU、LFU 和FIFO 多种淘汰算法,支持分布式的 Cache,可以作为 Hibernate 的缓存插件。同时它也能提供基于 Filter 的 Cache,该 Filter 可以缓存响应的内容并采用 Gzip 压缩提高响应速度。
百度百科对 EhCache的介绍如下:
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。
Ehcache 是一种广泛使用的开源 Java 分布式缓存。主要面向通用缓存,Java EE 和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个 gzip 缓存 servlet 过滤器,支持 REST 和SOAP api 等特点。
Ehcache最初是由 Greg Luck 于2003年开始开发。2009年,该项目被 Terracotta 购买。软件仍然是开源,但一些新的主要功能(例如,快速可重启性之间的一致性的)只能在商业产品中使用,例如 Enterprise EHCache and BigMemory。,维基媒体 Foundationannounced 目前使用的就是Ehcache技术。
EhCache 项目配置
在其官网下载 jar 包部署至项目 lib 下,然后在 src 目录下放置 ehcache.xml
文件。
EhCache 2 的 Maven 配置如下:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.1</version>
<type>pom</type>
</dependency>
如果使用 3.x 版本,则在 pom 文件中使用:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.0.0.m3</version>
</dependency>
EhCache配置文件和详细注释
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<!-- 默认配置 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<!-- 标签缓存1,用户实际配置的业务缓存示例 -->
<cache name="tagItemCache1"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="10800"
timeToLiveSeconds="10800"
overflowToDisk="true"
maxElementsOnDisk="10000"
diskPersistent="true"
/>
<!-- 标签缓存2 -->
<cache name="tagItemCache1"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="10800"
timeToLiveSeconds="10800"
overflowToDisk="true"
maxElementsOnDisk="10000"
diskPersistent="true"
/>
</ehcache>
<!--
设定具体的命名缓存的数据过期策略
cache元素的属性:
name:缓存名称
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大
eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。
注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。
diskPersistent:是否缓存虚拟机重启期数据。
clearOnFlush:内存数量最大时是否清除。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒
timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。
当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,
EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。
当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,
EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。
timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
可选策略有:LRU(最近最少使用,默认策略)、
FIFO(先进先出)、
LFU(最少访问次数)。
-->
EhCache 简单实用
在 2.x 版本中,一般通过 net.sf.ehcache.CacheManager
获取到缓存管理工具实例,在 3.x 版本中应该也有对应的工具,只是仓库坐标改变,换了 package 了。
EhCache 的一大特色就是简单快速,所有使用上也不复杂,具体 API 可以通过下面封装好的工具类便可以掌握。
/**
* EhCache管理工具
*/
public class EhcacheUtil
{
private static final String path = "/ehcache.xml";
private URL url;
private CacheManager manager;
private static EhcacheUtil ehCache;
private EhcacheUtil(String path)
{
url = getClass().getResource(path);
manager = CacheManager.create(url);
}
public static EhcacheUtil getInstance()
{
if (ehCache== null)
{
ehCache= new EhcacheUtil(path);
}
return ehCache;
}
public void put(String cacheName, String key, Object value)
{
Cache cache = manager.getCache(cacheName);
Element element = new Element(key, value);
cache.put(element);
}
public Object get(String cacheName, String key)
{
Cache cache = manager.getCache(cacheName);
Element element = cache.get(key);
return element == null ? null : element.getObjectValue();
}
public Cache get(String cacheName)
{
return manager.getCache(cacheName);
}
public void remove(String cacheName, String key)
{
Cache cache = manager.getCache(cacheName);
cache.remove(key);
}
}
EhCache 结合 Spring 4.x 工具类
Hibernate中的配置就不用说了,spring 中也提供了非常便利的缓存框架接口。如果你非常喜欢手动管理缓存,可以使用下面我简单封装的工具类。
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.stereotype.Component;
/**
* EhCache管理工具
*/
@Component
public class EhCacheUtil
{
@Autowired
private EhCacheManagerFactoryBean ehCacheManagerFactoryBean;
private CacheManager cacheManager;
/**
* 存储缓存,添加版本
* @param cacheName 缓存名称
* @param cacheKey 缓存键
* @param cacheValue 缓存值
* @param version 缓存版本
*/
public void put(String cacheName, Object cacheKey, Object cacheValue, long version)
{
Cache cache = getCacheManager().getCache(cacheName);
Element element = new Element(cacheKey, cacheValue, version);
cache.put(element);
}
/**
* 存储缓存,使用默认版本
* @param cacheName 缓存名称
* @param cacheKey 缓存键
* @param cacheValue 缓存值
*/
public void put(String cacheName, Object cacheKey, Object cacheValue)
{
put(cacheName, cacheKey, cacheValue, 1L);
}
/**
* 换取缓存对象
* @param cacheName 缓存名称
* @param cacheKey 缓存键
* @return 返回指定缓存对象
*/
public Object get(String cacheName, Object cacheKey)
{
Cache cache = getCacheManager().getCache(cacheName);
Element element = cache.get(cacheKey);
if (null == element)
{
return null;
}
return element.getObjectValue();
}
/**
* 删除缓存
* @param cacheName 缓存名称
* @param cacheKey 缓存键
* @return
*/
public boolean remove(String cacheName, Object cacheKey)
{
Cache cache = getCacheManager().getCache(cacheName);
return cache.remove(cacheKey);
}
/**
* 获取EhCache管理者
* @return
*/
public CacheManager getCacheManager()
{
return ehCacheManagerFactoryBean.getObject();
}
}
注意,工具类被使用了 @Component
注解,所以可以非常方便的像一般组件一样随时实例化:
@Autowired
private EhCacheUtil ehCacheUtil;
// 使用,添加一个缓存元素
ehCacheUtil.put(cacheName, elementName, elementValue);
EhCache 与 Memcache 和 Redis 之间的比较
一般来说,我在选择缓存框架的时候,Memcache 是自动忽视的,所以不是很了解。
对于EhCache 和 Redis 之间的比较,一般有下面这些观点,仅供参考。
EhCache
在 Java 项目广泛的使用。它是一个开源的、设计于提高在数据从 RDBMS 中取出来的高花费、高延迟采取的一种缓存方案。正因为 EhCache 具有健壮性(基于 Java 开发)、被认证(具有 apache 2.0 license)、充满特色,所以被用于大型复杂分布式 web application 的各个节点中。
- 够快
EhCache 的发行有一段时长了,经过几年的努力和不计其数的性能测试,EhCache 终被设计于large, high concurrency systems。
- 够简单
开发者提供的接口非常简单明了,从 EhCache 的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用 EhCache,EhCache 被广泛的运用于其他的开源项目,比如:Hibernate。
- 够袖珍
关于这点的特性,官方给了一个很可爱的名字 small foot print ,一般 EhCache 的发布版本不会到2M,V2.2.3 才 668KB。
- 够轻量
核心程序仅仅依赖 slf4j 这一个日志包,没有之一!
- 好扩展
EhCache 提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供 LRU、LFU、FIFO 淘汰算法,基础属性支持热配置、支持的插件多。
- 监听器
缓存管理器监听器
(CacheManagerListener)和缓存监听器
(CacheEvenListener),做一些统计或数据一致性广播挺好用的。
如何使用?够简单就是EhCache的一大特色。相信你从上面的两个工具类中就可以了解到。
Redis
Redis 是在 Memcache 之后编写的,大家经常把这两者做比较,如果说它是个 key-value store 的话但是它具有丰富的数据类型,我想暂时把它叫做缓存数据流中心,就像现在物流中心那样,order、package、store、classification、distribute、end。现在还很流行的 LAMP PHP 架构不知道和 redis+mysql 或者 redis + mongodb 的性能比较。
- 支持持久化
Redis 的本地持久化支持两种方式:RDB
和 AOF
。RDB 在 redis.conf 配置文件里配置持久化触发器,AOF 指的是 Redis 每增加一条记录都会保存到持久化文件中(保存的是这条记录的生成命令),如果不是用 Redis 做 DB 用的话还是不要开 AOF,数据太庞大了,重启恢复的时候是一个巨大的工程!
- 丰富的数据类型
Redis 支持 String 、Lists、sets、sorted sets、hashes 多种数据类型,新浪微博会使用 Redis 做 nosql 主要也是它具有这些类型,时间排序、职能排序、我的微博、发给我的这些功能 List 和 sorted set 的强大操作功能息息相关。
- 高性能
这点跟 Memcache 很相像,内存操作的级别是毫秒级的比硬盘操作秒级操作自然高效不少,较少了磁头寻道、数据读取、页面交换这些高开销的操作!这也是 NOSQL 冒出来的原因吧,应该说高性能是基于 RDBMS 的衍生产品,虽然 RDBMS 也具有缓存结构,但是始终在 app 层面不是我们想要的那么操控的。
-
replication
Redis 提供主从复制方案,跟 mysql 一样增量复制而且复制的实现都很相似,这个复制跟 AOF 有点类似复制的是新增记录命令,主库新增记录将新增脚本发送给从库,从库根据脚本生成记录,这个过程非常快,就看网络了,一般主从都是在同一个局域网,所以可以说 Redis 的主从近似及时同步,同事它还支持一主多从,动态添加从库,从库数量没有限制。 主从库搭建,我觉得还是采用网状模式,如果使用链式(master-slave-slave-slave-slave·····)如果第一个 slave 出现宕机重启,首先从 master 接收数据恢复脚本,这个是阻塞的,如果主库数据几 TB 的情况恢复过程得花上一段时间,在这个过程中其他的 slave 就无法和主库同步了。
-
更新快
这点好像从我接触到 Redis 到目前为止 已经发了大版本就4个,小版本没算过。Redis 作者是个非常积极的人,无论是邮件提问还是论坛发帖,他都能及时耐心的为你解答,维护度很高。有人维护的话,让我们用的也省心和放心。目前作者对 Redis 的主导开发方向是 Redis 的集群方向。
所以如果希望简单高效
就用 EhCache,如果开发任务比较复杂
,希望得到比较多的支持什么的就 Redis。