搜索
您的当前位置:首页正文

ehcache使用文档

来源:星星旅游


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最基本和简单的例子。配置文件内容如下:

第 5 页 共 23页

Ehcache使用文档

maxEntriesLocalDisk=\"1000\" eternal=\"false\" overflowToDisk=\"true\" diskSpoolBufferSizeMB=\"20\" timeToIdleSeconds=\"300\" memoryStoreEvictionPolicy=\"LFU\" transactionalMode=\"off\" /> timeToLiveSeconds=\"600\" 经过以上步骤操作,我们的工程如下图3.2所示:

图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中的项的配置创建出一个name为“sampleCache1”的cache。

多例创建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配置文件的内容为: class=\"net.sf.ehcache.distribution.RMICacheManagerPeerListenerFac properties=\"port=40000,socketTimeoutMillis=120000\" /> tory\" class=\"net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory\" overflowToDisk=\"true\" overflowToDisk=\"false\">

第 17 页 共 23页

Ehcache使用文档

\" class=\"net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory properties=\"bootstrapAsynchronously=false\" /> 然后,将ehcache-test工程的ehcache_cluster.xml拷贝一份到ehcache-test-b工程对应目录下;修改ehcache-test-b工程中的ehcache_cluster.xml中的cacheManagerPeerProviderFactory配置项内容为: class=\"net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory\" properties=\"port=60000,socketTimeoutMillis=120000\" /> 第 18 页 共 23页

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\" />

此段配置定义了网络集群环境中其他提供数据同步的主机声明。Properties属性主要由两个属性,peerDiscovery和rmiUrls。其说明如下:

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:

第 21 页 共 23页

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:

class=\"net.sf.ehcache.distribution.RMICacheReplicatorFactory\" />

timeToIdleSeconds=\"100000\" timeToLiveSeconds=\"100000\" overflowToDisk=\"false\">

需要同步数据的缓存中加入cacheEventListenerFactory配置。

5.2 集群模式中的其他特性说明

对于集群环境中使用ehcache实现数据同步的过程中,采用RMI方式的时候,数据只有被put、remove等操作时,才会将数据同步到其他主机中。因为这样,就可能会出现这样的问题:当一个节点中的服务器停机了,当重新启动该节点服务器时,服务器中的cache数据为空。我们希望,这个时候,该节点能迅速从其他各个节点中得到已经被缓存的数据。

针对这个问题,Ehcache的缓存配置中,有这样一个配置bootstrapCacheLoaderFactory。完整的配置如下:

\"

第 22 页 共 23页

timeToIdleSeconds=\"100000\" timeToLiveSeconds=\"100000\"

overflowToDisk=\"false\">

class=\"net.sf.ehcache.distribution.RMICacheReplicatorFactory\" /> class=\"net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory

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页

因篇幅问题不能全部显示,请点此查看更多更全内容

Top