MRanger 2012-11-09
Ehcache是Java平台常用的缓存组建,也是hibernate目前默认的二级缓存实现。使用Java构建互联网应用,缓存是不可缺少的环节,Ehcache登场率也相当高。
Grails集成了Hibernate作为ORM持久化的方案,默认也使用Ehcache作为缓存。
比起Php等技术常常使用memcached作为缓存相比,Ehcache省去了数据类型转换的复杂步骤,而且无缝集成hibernate,并且是JVM内的数据,所以对于Java应用来说更加方便快捷。
只是一旦应用需要分布式或者集群,JVM内部的缓存非但没有多大帮助反倒是成了累赘,数据同步是一个极大的障碍。所以Ehcache集群方案也十分重要。Ehcache本身有多种集群同步方案,包括RMI、JGROUPS、JMS。这几种方案在和Grails集成过程中都遇到了很大的障碍,而且国内资料讨论相对少,调试不通过故障也不清楚。另外如果集群节点很多,那么通过广播的方式同步数据,终究不是一个高效率的方案,虽然我没亲自做过测试。
Terracotta是一个极品又奇葩的软件(褒义),我看到网上使用它在不修改源码的情况下,将两个JVM中四个线程互锁数据实现的Demo,我感到十分震撼。用Terracotta实现Ehcache集群,配置相对简单,而且不容易出错。并且感觉上,效率更高,内存利用率也更高。而且作为Java的缓存集群方案,它的扩展性很强,作为一个集群缓存方案非常合适。(本段属于个人感觉,没有实验数据,仅供参考)
接下来是我在Grails中配置Terracotta实现ehcache缓存的步骤
Grails版本1.3.9
1.3.9中,Grails默认的ehcache版本是1.71。这个时候的ehcache可能还没有被Terracotta收购,和Terracotta的集成未必顺利,所以我升级到目前最新版本2.62,并且导入ehcache和Terracotta集成的工具。在BuildConfig.groovy文件中配置如下
inherits("global"){
//uncommenttodisableehcache
//excludes'ehcache'
runtime'net.sf.ehcache:ehcache-core:2.6.2'
runtime'net.sf.ehcache:ehcache-terracotta:2.6.2'
runtime'org.terracotta:terracotta-toolkit-1.2-runtime:3.1.0'
}
利用maven自动下载jar包,继续配置BuildConfig.groovy加入新资源
repositories{
grailsPlugins()
grailsHome()
grailsCentral()
mavenRepo"http://www.terracotta.org/download/reflector/releases"
}
然后在conf目录下创建ehcache.xml文件配置缓存
加入节点
<terracottaConfigurl="localhost:9510"/>
链接Terracotta服务器,然后只需要在需要进行集群缓存的cache中增加标签<terracotta/>即可
例如查询缓存的配置:
<cachename="org.hibernate.cache.StandardQueryCache"
maxEntriesLocalHeap="10000"
timeToIdleSeconds="300"
><terracotta/></cache>
default是否可以配置<terracotta/>我还不确定
然后安装terracotta。我下载了最新的Terracotta3.7.2,使用java-jar命令进行安装。linux下如何命令安装还没有尝试。安装完成后启动start-tc-server.bat|sh服务,默认端口即是9510
然后启动Grails程序即可链接到Terracotta,即可成功连接缓存。
Terracotta对于配置的cache,集群环境中如果配置文件不一致,目前我观察只以其中一个有效,感觉还做不到各有各的效果。我感觉是最其中配置最大的生效,例如时间或者数量的上限。也可能是第一个链接服务器的生效。具体的没有详细测试,有待继续研究。