Ehcache使用文档
Ehcache使用文档
作者:sunyf
2013年11
月
第 1 页 共 23页
Ehcache使用文档
1 基本介绍
1.1 前言
Ehcache是一个快速的、轻量级的、易于使用的、进程内的缓存。它支持read-only 和read/write 缓存,内存和磁盘缓存。是一个非常轻量级的缓存实现,而且从1.2 之后就支持了集群,目前的最新版本是2.5。
简单地说来,ehcache有以下特点: 快速. 简单. 多种缓存策略
缓存数据有两级:内存和磁盘,因此无需担心容量问题 缓存数据会在虚拟机重启的过程中写入磁盘 可以通过RMI、可插入API 等方式进行分布式缓存 具有缓存和缓存管理器的侦听接口
支持多缓存管理器实例,以及一个实例的多个缓存区域 提供Hibernate 的缓存实现
2 安装和使用
2.1 下载
Ehcache的官方网站http://ehcache.org/downloads/catalog 上面可以下载到各种版本。目前用最新版本是2.5.1,下载这个版本即可。(下载之前,会要求用户注册,按照要求输入即可)。 建议下载ehcache-2.5.1-distribution.tar.gz文件,因为这个文件包含了所有Ehcache的内容。
第 2 页 共 23页
Ehcache使用文档
2.2 安装
2.2.1 发布包内容说明
将ehcache-2.5.1-distribution.tar.gz解压到本地文件系统。在安装之前,我们先来大致看看发布包里边的内容,如下图2.1所示。
图2.1
如一般的开源框架发布包类似,ehcahce的发布包包含以下目录内容: javadoc:ehcache的API文档;
lib:ehcache要用到的第三方jar包和自己的jar包; licenses:ehcache的授权文件; samples:ehcache的例子目录; src:ehcache的源代码目录;
terracotta:使用terracotta集群时的terracotta服务;
ehcache.xml:ehcache的配置文件模板,包括各个配置的英文解释; ehcache.xsd:ehcache.xml文件的验证文件模板;
QUICK-START.html:快速开始文件,会连接到ehcache的官方网站; README.html:ehcache版本功能和新特性说明文件。
除了阅读本文档快速地学习和了解ehcache的功能,也可以通过ehcache
第 3 页 共 23页
Ehcache使用文档
自带的快速开始文件进行学习。
2.2.2 安装到项目工程
Ehcache的安装方法比较简单,将解压开的发布包下的lib /ehcache-core-2.5.1.jar、lib /slf4j-api-1.6.1.jar和lib/slf4j-jdk14-1.6.1.jar放置到类路径下面即可使用。如下图2.2所示:
图2.2
其中,slf4j-api-1.6.1.jar和slf4j-jdk14-1.6.1.jar两个jar包,用于ehcache的日志输出,是第三方jar包。关于这两个jar包的用法和功能特性,请查阅slf4j框架的相关功能。
3 开始一个例子
3.1 新建一个空的java project工程
通过eclipse向导新建一个Java Project工程ehcache-test,并将上面提的三个类添加到类路径下。工程如下图3.1所示:
图3.1
其中的lib目录,我专门用来存放jar包。
第 4 页 共 23页
Ehcache使用文档
3.2 工程中添加配置文件
3.2.1 新建配置文件存放目录
在ehcache-test工程中新建专门用于存放配置文件的包,根据我们的习惯,该包取名为“conf”。
3.2.2 加入ehcache配置文件
在刚才新建的conf包下加入发布包目录下的ehcache.xml和ehcache.xsd两个配置文件。(注意,这两个配置文件要放在同一目录下。如果需要将ehcache.xsd文件放到其他目录,需要修改ehcache.xml文件中的xsi:noNamespaceSchemaLocation=\"ehcache.xsd\"配置项)
经过以上步骤操作,工程目录结构如下图3.2所示:
3.2.3 修改ehcache.xml配置文件内容
正如先前所述,ehcache.xml是ehcache的配置文件模板,每一项配置的说明都相当详细。在修改该配置文件之前,如果大家有兴趣,不妨先大致看看其中的内容和注释。
为了说明简单,我们先运行ehcache最基本和简单的例子。配置文件内容如下: Ehcache使用文档 maxEntriesLocalDisk=\"1000\" eternal=\"false\" overflowToDisk=\"true\" diskSpoolBufferSizeMB=\"20\" timeToIdleSeconds=\"300\" memoryStoreEvictionPolicy=\"LFU\" transactionalMode=\"off\" /> timeToLiveSeconds=\"600\"
图3.2
3.3 编写测试类
新建名为“ehcache”的包。在“ehcache”包下面新建“TestMain.java”
类。
TestMain.java文件内容使用Junit来编写,所以我们还需要在工程中添加Junit4。TestMain.java的内容很简单,如下:
package ehcache;
import java.net.URL;
import junit.framework.TestCase; import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; /** *
* @author ldp * */
public class TestMain {
第 6 页 共 23页
Ehcache使用文档
}
@Test
public void testF1() throws Exception { }
URL url = TestMain.class.getClassLoader().getResource(
\"conf/ehcache.xml\");
CacheManager manager = new CacheManager(url); Cache cache1 = manager.getCache(\"sampleCache1\"); String key = \"key1\";
String value = key.hashCode() + \"\";
Element element1 = new Element(key, value); cache1.put(element1);
System.out.println(cache1.get(key));
manager.shutdown();
以上是一个很简单的测试类,稍后我们再对代码进行分析。
3.4 运行测试类
运行上面的TestMain.java类,输出结果如下:
3.5 代码解析
下面主要对TestMain.java中的testF1()方法进行详细地解析。 代码片段1:
URL url = TestMain.class.getClassLoader().getResource(
\"conf/ehcache.xml\");
CacheManager manager = new CacheManager(url);
这两行代码根据conf/ehcache.xml配置文件新建出一个CacheManager对
第 7 页 共 23页
Ehcache使用文档
象。也就是说,一个ehcache.xml文件就对应一个CacheManager对象,ehcache.xml中配置的各个缓存,即为该CacheManager对象实际管理和控制的cache对象。
代码片段2:
Cache cache1 = manager.getCache(\"sampleCache1\");
通过CacheManager对象获取其中的指定缓存(sampleCache1)。每个缓存以其name属性来区分。
代码片段3:
String key = \"key1\";
String value = key.hashCode() + \"\";
新建一个键值对。 代码片段4:
Element element1 = new Element(key, value); cache1.put(element1);
System.out.println(cache1.get(key));
新建一个Element对象,该对象以刚才的键值对为数据;再将Element对象放入到缓存sampleCache1中;再从缓存sampleCache1中根据键取出存入其中的Element对象。
代码片段5:
manager.shutdown();
关闭CacheManager对象,程序运行结束。
4 Ehcache的基本原理
通过以上的一个简单的例子,我们已经大体了解了一些Ehcache的原理。接下来,我们再比较详细地了解下Ehcache的原理。
4.1 整体结构
Ehcache的类层次模型主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单个的CacheManager,或者通过CacheManager的构造函数创建一个新的CacheManager。每个CacheManager都管理着多个Cache。而每个Cache都以一种类Hash的方式,关联着多个Elemenat。而Element则是我们用于存放要缓存内容的地方。
Ehcache的整体结构图如下图4.1所示。
第 8 页 共 23页
Ehcache使用文档
图4.1 ehcache的刷新策略
ehcache的刷新策略是当缓存在放入的时候记录一个放入时间,它是用Lazy Evict的方式,在取的时候同设置的TTL比较。
ehcache缓存的3种清空策略: FIFO,先进先出
LFU,最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出
缓存。 LRU,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而
又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 事件处理
可以为CacheManager添加事件监听,当对CacheManager增删Cache时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
可以为Cache添加事件监听,当对Cache增删Element时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
4.2 CacheManager
如上文所述,CacheManager是操作Ehcache的入口。其类结构如下:
第 9 页 共 23页
Ehcache使用文档
对于CacheManager,我么重点了解它的构造函数。我们可以有两种模式来创建CacheManager,单例(Singleton)和多例(Instance)。
单例创建CacheManager是指通过CacheManager.getInstance()方法或者无参的构造函数CacheManager()创建一个CacheManager对象。这种情况下,系统会在最顶层的classpath路径下找名叫ehcache.xml的配置文件,如果查找失败,会以ehcache-core-2.5.1.jar包中的ehcache-failsafe.xml文件(里边的缓存配置极其简单)替代。同时,一个警告会提醒用户建立自己的配置文件。
测试代码(添加在ehcache-test工程的TestMain.java中,以下同是):
@Test
public void testF2() throws Exception {
CacheManager manager = new CacheManager(); manager.addCache(\"sampleCache1\");
Cache cache1 = manager.getCache(\"sampleCache1\"); String key = \"key1\";
String value = key.hashCode() + \"\";
Element element1 = new Element(key, value); cache1.put(element1);
System.out.println(cache1.get(key));
第 10 页 共 23页
Ehcache使用文档
manager.shutdown();
}
执行结果如下图4.2所示:
图4.2
同时,我们也可以看到,当我们用代码“manager.addCache(\"sampleCache1\");”向CacheManager中加入缓存时,系统会自动用ehcache-failsafe.xml中的 多例创建CacheManager的方法和先前的testF1()方法一致。CacheManager支持多种方式创建:Configuration对象、InputStream对象、配置文件路径字符串和URL对象。如果大家有兴趣,都可以去尝试一下。 特别地,对于多例创建CacheManager,我们需要指定CacheManager的name属性,系统不允许多个相同name的CacheManager存在;另外,对于一些资源,如当设置了cache内存占用空间满了后,就将缓存数据存放到物理硬盘上(Cache的overflowToDisk属性),每个CacheManager对象的diskStore配置路径不能有重复。关于diskStore的详细配置说明,请参照ehcache.xml模板文件。 4.3 Ehcache接口 所有的cache都实现此接口,每个cache有自己的name和其他属性,cache中存放Element对象数据。Cache中的Element对象一般存储在MemoryStore里边,我们也可以配置将其存储到DiskStore配置指定的文件路径下边。该接口的结构如下: 第 11 页 共 23页 Ehcache使用文档 第 12 页 共 23页 Ehcache使用文档 4.4 Element Element对象是存储在cache对象中的最基本元素,主要由键、值和访问记录三部分信息要素构成。 如果cache的配置只是让Element存放在MemoryStore中,对Element对象存储的值没有特殊要求;如果cache配置让Element对象存放在DiskStore中,或者在集群环境里cache信息复制时,则要求Element对象存储的值是可序列化的(Serializable)。如果不可序列化的对象被放到DiskStore中,或者集群中复制,则这些信息将被丢失,不会有error产生,只产生debug级别的日志。 Element类的结构如下所示: 第 13 页 共 23页 Ehcache使用文档 第 14 页 共 23页 Ehcache使用文档 5 集群环境下使用缓存 Ehcache支持多种集群环境下的使用。不同的集群环境,ehcache.xml的配置不一样。 Ehcache支持以下五种集群方式: Terracotta RMI JMS JGroups EhCache Server 我们主要看最常用的一种方式:RMI。 5.1 RMI 集群模式 RMI 是 Java 的一种远程方法调用技术,是一种点对点的基于 Java 对象的通讯方式。EhCache 从 1.2 版本开始就支持 RMI 方式的缓存集群。在集群环境中 EhCache 所有缓存对象的键和值都必须是可序列化的,也就是必须实现 java.io.Serializable 接口,这点在其它集群方式下也是需要遵守的。 5.1.1 RMI集群模式结构及原理 RMI 集群模式的结构如下图5.1所示: 图5.1 第 15 页 共 23页 Ehcache使用文档 采用 RMI 集群模式时,集群中的每个节点都是对等关系,并不存在主节点或者从节点的概念,因此节点间必须有一个机制能够互相认识对方,必须知道其它节点的信息,包括主机地址、端口号等。EhCache 提供两种节点的发现方式:手工配置和自动发现。手工配置方式要求在每个节点中配置其它所有节点的连接信息,一旦集群中的节点发生变化时,需要对缓存进行重新配置。 由于RMI是Java 中内置支持的技术,因此使用 RMI 集群模式时,无需引入其它的Jar包,Ehcache 本身就带有支持 RMI 集群的功能。使用 RMI 集群模式需要在ehcache.xml 配置文件中定义 cacheManagerPeerProviderFactory 节点。 5.1.2 RMI集群例子 我们可以按照以下步骤来进行来完成这个例子: 1) 按照第3章相同的方法新建一个java工程ehcache-test-b; 我们工作空间工程结构如下图5.2所示: 图5.2 (注意:ehcache-test-b工程的测试类名为TestMainB,以方便后续 第 16 页 共 23页 Ehcache使用文档 在Eclipse的console里区分) 2) 修改ehcache.xml配置文件; 为了保存先前的成果,我们新建一份名为ehcache_cluster.xml的配置文件。 ehcache_cluster.xml配置文件的内容为: 第 17 页 共 23页 Ehcache使用文档 \" Ehcache使用文档 图5.3 3) 编写java测试方法 在ehcache-test工程的TestMain.java文件中添加以下代码: 第 19 页 共 23页 @Test public void testF3() throws Exception { URL url = TestMain.class.getClassLoader().getResource( \"conf/ehcache_cluster.xml\"); CacheManager manager = new CacheManager(url); Cache cache1 = manager.getCache(\"UserCache\"); String key = \"key1\"; String value = key.hashCode() + \"\"; Element element1 = new Element(key, value); cache1.put(element1); System.out.println(cache1.get(key)); Ehcache使用文档 manager.shutdown(); } 在ehcache-test-b工程的TestMainB.java文件中添加以下代码: @Test public void testF3() throws Exception { URL url = TestMainB.class.getClassLoader().getResource( \"conf/ehcache_cluster.xml\"); CacheManager manager = new CacheManager(url); Cache cache1 = manager.getCache(\"UserCache\"); while (true) { } manager.shutdown(); String key = \"key1\"; System.out.println(\"get value by aaa\"); Element element = cache1.get(key); if (element != null) { } Thread.sleep(1000); System.out.println(element.getValue()); break; } 4) 运行测试程序; 先运行ehcache-test-b工程的TestMainB.java文件中testF3()方法,再运行ehcache-test工程的TestMain.java文件中testF3()方法。在正常情况下,不久会,程序就可运行完成。 ehcache-test-b工程运行的结果如下图5.4所示: 图5.4 ehcache-test工程运行的结果如下图5.5所示: 第 20 页 共 23页 Ehcache使用文档 图5.5 我们可以看到,正如我们所说,集群下的缓存数据同步实现了。 5.1.3 RMI集群配置文件说明 要实现RMI集群环境下缓存数据同步,我们只要修改好缓存配置文件就可以了。 配置文件片段1: class=\"net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory\" properties=\"peerDiscovery=manual,rmiUrls=//127.0.0.1:60000/UserCache|//127.0.0.1:40000/UserCache\" /> peerDiscovery= automatic:自动发现其他主机; peerDiscovery= manual:指定其他主机列表。 当peerDiscovery= automatic时,我们还需要指定以下属性值: multicastGroupAddress:组播地址;如230.0.0.1 multicastGroupPort:组播主机端口;如60000 timeToLive:组播传播范围;如32 当peerDiscovery= manual时,正如上面例子一样,我们只需要列出所有的其他主机列表,例如: rmiUrls=//127.0.0.1:60000/UserCache|//127.0.0.1:40000/UserCache 为了配置方便,我们可以把本机也配置在主机列表中,如例子所示。 配置文件片段2: Ehcache使用文档 class=\"net.sf.ehcache.distribution.RMICacheManagerPeerListenerFac properties=\"port=40000,socketTimeoutMillis=120000\" /> tory\" 正如注释描述的,此处申明本机的ip和端口号,以使得其他主机能发现本机。Properties可以配置的属性如下: hostName:主机ip;默认为127.0.0.1 port:主机端口号;如60000 socketTimeoutMillis:socket超时时间设置;如120000 配置文件片段3: timeToIdleSeconds=\"100000\" timeToLiveSeconds=\"100000\" 需要同步数据的缓存中加入cacheEventListenerFactory配置。 5.2 集群模式中的其他特性说明 对于集群环境中使用ehcache实现数据同步的过程中,采用RMI方式的时候,数据只有被put、remove等操作时,才会将数据同步到其他主机中。因为这样,就可能会出现这样的问题:当一个节点中的服务器停机了,当重新启动该节点服务器时,服务器中的cache数据为空。我们希望,这个时候,该节点能迅速从其他各个节点中得到已经被缓存的数据。 针对这个问题,Ehcache的缓存配置中,有这样一个配置bootstrapCacheLoaderFactory。完整的配置如下: \" 第 22 页 共 23页 overflowToDisk=\"false\"> Ehcache使用文档 properties=\"bootstrapAsynchronously=false\" /> 有兴趣的读者,可以将此配置拷贝到自己的测试工程配置文件中,编写java测试方法来模拟上述情况,并查看结果。 6 总结 在现在的IT应用中,有很多cache的产品或者框架,比如jbosscache、OScache、MemCache,当然还有Ehcache等等。其中用得最为广泛的,应该是Ehcache和MemCache。 Ehcache的特点前面已经有所描述,这里不再赘述。简单地说,在java的较小型的项目中,一般都采用Ehcache。 MemCache作为大型项目或者网站常采用的分布式缓存方案,在分布式集群方面有其独特之处。MemCache一般需要单独部署在一台服务器上,而Ehcache常常作为java应用系统的一个插件部分用于项目中。 Ehcache的功能很强大,更多地关于Ehcache的使用,请参照其官方使用手册。 第 23 页 共 23页 因篇幅问题不能全部显示,请点此查看更多更全内容