EHCache 配置详解
thanks
EHCache是一个纯java的在进程中的缓存,它具有以下特性:快速,简单,为Hibernate2.1充当可插入的缓存,最小的依赖性,全面的文档和测试.官方网站http://ehcache.sourceforge.net/
毫无疑问,几乎所有的网站的首页都是访问率最高的,而首页上的数据来源又是非常广泛的,大多数来自不同的对象,而且有可能来自不同的db,所以给首页做缓存是一个不错的主意,那么主页的缓存策略是什么样子的呢,我认为应该是某个固定时间之内不变的,比如说2分钟更新一次.那么这个缓存应该做在什么地方呢,让我们来看一下,假设您的应用的结构是page-filter-action-service-dao-db,这个过程中的-的地方都是可以做缓存的地方,根据页面缓存的特征,应该把页面缓存做到尽量靠近客户的地方,就是在page和filter之间,这样的优点就是第一个用户请求之后,页面被缓存,第二个用户再来请求的时候,走到filter这个请求就结束了,无需再走后面的action-service-dao-db.带来的好处是服务器压力的减低和客户段页面响应速度的加快.
那么我们来看一下如何使用ehcache做到这一点.
在使用ehcache的页面缓存之前,我们必须要了解ehcache的几个概念,
1timeToIdleSeconds,多长时间不访问该缓存,那么ehcache就会清除该缓存.
2timeToLiveSeconds,缓存的存活时间,从开始创建的时间算起.
首页的页面缓存的存活时间,我们定的是2分钟,timeToLiveSeconds应该设置为120,同时我们的timeToIdleSeconds最好也设置为2分钟,或者小于2分钟.我们来看一下下面这个配置,这个配置片段应该放到ehcache.xml中:
<cachename="SimplePageCachingFilter"
maxElementsInMemory="10"
maxElementsOnDisk="10"
eternal="false"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="10"
timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LFU"
/>
SimplePageCachingFilter是缓存的名字,maxElementsInMemory表示内存中SimplePageCachingFilter缓存中元素的最大数量为10,maxElementsOnDisk是指持久化该缓存的元素到硬盘上的最大数量也为10,eternal=false意味着该缓存会死亡.overflowToDisk=true意思是表示当缓存中元素的数量超过限制时,就把这些元素持久化到硬盘,如果overflowToDisk是false,那么maxElementsOnDisk的设置就没有什么意义了.memoryStoreEvictionPolicy=LFU是指按照缓存的hit值来清除,也就是说缓存满了之后,新的对象需要缓存时,将会将缓存中hit值最小的对象清除出缓存,给新的对象腾出地方来了(文章最后有ehcache中自带的3种缓存清空策略的介绍).
SimplePageCachingFilter的配置,
<filter>
<filter-name>indexCacheFilter</filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>indexCacheFilter</filter-name>
<url-pattern>*index.action</url-pattern>
</filter-mapping>
就只需要这么多步骤,我们就可以给某个页面做一个缓存的,把上面这段配置放到你的web.xml中,那么当你打开首页的时候,你会发现,2分钟才会有一堆sql语句出现在控制台上.当然你也可以调成5分钟,总之一切都在控制中.
好了,缓存整个页面看上去是非常的简单,甚至都不需要写一行代码,只需要几行配置就行了,够简单吧,虽然看上去简单,但是事实上内部实现却不简单哦,有兴趣的话,大家可以看看SimplePageCachingFilter继承体系的源代码.
上面的配置针对的情况是缓存首页的全部,如果你只想缓存首页的部分内容时,你需要使用SimplePageFragmentCachingFilter这个filter.我们看一下如下片断:
<filter>
<filter-name>indexCacheFilter</filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>indexCacheFilterfilter-name>
<url-pattern>*/index_right.jsp</url-pattern>
</filter-mapping>
这个jsp需要被jsp:include到其他页面,这样就做到的局部页面的缓存.这一点貌似没有oscache的tag好用.
事实上在cachefilter中还有一个特性,就是gzip,也就是说缓存中的元素是被压缩过的,如果客户浏览器支持压缩的话,filter会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户浏览器,如果客户的浏览器不支持gzip,那么filter会把缓存的元素拿出来解压后再返回给客户浏览器(大多数爬虫是不支持gzip的,所以filter也会解压后再返回流),这样做的优点是节省带宽,缺点就是增加了客户浏览器的负担(但是我觉得对当代的计算机而言,这个负担微乎其微).
好了,如果你的页面正好也需要用到页面缓存,不防可以考虑一下ehcache,因为它实在是非常简单,而且易用.
总结:ehcache是一个非常轻量级的缓存实现,而且从1.2之后就支持了集群,目前的最新版本是1.3,而且是hibernate默认的缓存provider.虽然本文是介绍的是ehcache对页面缓存的支持,但是ehcache的功能远不止如此,当然要使用好缓存,对JEE中缓存的原理,使用范围,适用场景等等都需要有比较深刻的理解,这样才能用好缓存,用对缓存.
ehcache中缓存的3种清空策略:
1FIFO,firstinfirstout,这个是大家最熟的,先进先出,不多讲了
2LFU,LessFrequentlyUsed,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的.如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存.
2LRU,LeastRecentlyUsed,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存.
简介
Ehcache俩中缓存机制:
·MemoryStore(内存存储)
·DiskStore(磁盘存储)
MemoryStore
MemoryStore总是可用的,但不可直接操作,当中存储着所有的Cache.
·合适的Element类型
所有的Element都可以放在MemoryStore中.
·安全性:使用多个线程并行检查内存泄露.
·JDK:使用了JDK1.5的LinkedHashMap来存放Elemen.t
·快速的:是最快的缓存机制,因为它是存放在内存中.
·失效策略(Memory)
Cache可以配置最大缓存Element的个数,以及失效时间.如果在添加Elemtent时,缓存中的Element个数达到了最大缓存数并且overflowToDisk配置的属性为true,Ehcache会更具配置项MemoryStoreEvictionPolicy的失效策略将Element输出到磁盘.如果overflowToDisk为fasle,Ehcache将删除内存中Element.Ehcache支持三种失效策略:LRU,LFU,FIFO.
值得注意的是缓存中失效的Element并不会别马上清理掉,所以想得到内存的真实大小应该调用方法calculateInMemorySize()方法.
DiskStore
DiskStore可缓存到外部设备上(硬盘).
·DiskStoresareOptional
Ehcache从1.5版本开始支持DiskStore.如果你需要多个DiskStore的话,最好给他们配置不同的文件路径.
·关闭磁盘缓存:只要注释掉ehcache.xml配置文件中的磁盘缓存配置项即可.而ehcache-failsafe.xml的磁盘缓存配置不会影响到你自己的cache.
·合适的Element类型
这里要注意要想使用磁盘缓存,缓存的Element必须实现序列化接口.否则会抛出NotSerializableException异常.
·存储:Ehcache会将每个缓存配置的文件路径下创建一个cache_name.data文件,如果使用的磁盘持久化技术,还会生成一个cachename.index文件.
·失效
Ehcache有一个后台线程专门做Ellment失效监测以及清除工作.设置线程运行间隔时间,可通过设置diskExpiryThreadIntervalSeconds属性来完成,此值不宜设置过低,否则会导致清理线程占用大量CPU资源.默认值是120秒.
·持久化
持久化可在Element的diskPersistent配置项中配置,如果配置为"false"或是"omitted"在CacheManagershutdown或是startup后,用来缓存Element的文件将被清除掉.如果设置为"true",data和index文件会被保存下来,对于新创建的CacheManagerElement也是可用的.
使用时必须显示调用cache.Flush()才会将数据缓存到磁盘中.
磁盘缓存步骤:从MemoryStore中把没有失效的Element刷新到DiskStore,Element被写入到data文件,Element将被序列化到index文件.
Ehcache缓存回收策略
缓存回收就是当缓存满了的时候,Ehcache会根据指定的策略来清理缓存.这里的缓存回收策略有别与Ehcache中的失效清理策略.失效清理策略是对失效的Element进行批量清理时所采用的策略,最终所有失效的Element都将被清理,只不过是清理的先后顺序不同罢了.Ehcache中缓存的最大Element数是由maxElementsInMemory来指定的.当缓存中的Element个数达到maxElementsInMemory指定的值时,Ehcache会根据具体的策略来清理缓存,默认的策略是LRU(最近最少使用).
磁盘缓存大小默认是没有限制的,不过可通过maxElementsOnDisk来指定.当磁盘缓存达到maxElementsOnDisk指定的值时,Ehcache会清理磁盘中的缓存使用默认策略是LFU(使用频率最低).
MakesureyouareusingasupportedJavaversion.
PlacetheEhcachejarintoyourclasspath.
Ensurethatanylibrariesrequiredtosatisfydependenciesarealsointheclasspath.
Configureehcache.xmlandplaceitinyourclasspath.
Optionally,configureanappropriatelogginglevel.
Downloads:http://sourceforge.net/projects/ehcache/files/
Welcometoehcache:http://ehcache.org/