EhCache
Java 캐싱 프레임워크로 단일 JVM 캐싱과 분산 (distributed/clustered) 캐싱을 지원한다.
Hibernate와의 연동도 잘 된다.
일반 설정
- 설정 XML 파일(ehcache.xml 혹은 기타 이름 직접 지정)은 jar 로 묶으면 작동하지 않는다. 압축이 풀려 있는 클래스 패스로 지정된 디렉토리에 둔다.
- ehcache의 jar 파일들과 설정 파일이 동일 클래스로더 영역에 있어야 한다.
- EhCache 기본 설정을 참조하여 기본 설정을 할 수 있다. 그러나 복잡한 것 필요없이 아래 설정만으로도 기본적인 캐싱을 수행할 수 있다. defaultCache만 있어도 직접 지정되지 않은 다른 캐시를 모두 defaultCache가 캐싱해주기 때문에 문제는 없다.
- <?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="50000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
분산 캐싱
아래 사항은 각 서버별로 모두 동일하게 적용해 줘야 한다.
- <defaultCache maxElementsInMemory="50000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</defaultCache>
분산 캐싱을 할 때는 각 캐시별로 cacheEventListenerFactory를 등록해준다. 가장 쉬은 것은 RMICacheReplicatorFactory이다.
- <cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
multicastGroupPort=3209, timeToLive=32" /> - <cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="port=3208, socketTimeoutMillis=2000" />
그리고서 cacheManagerPeerProviderFactory와 cacheManagerPeerListenerFactory를 각 분산 캐싱 설정파일들에 모두 설정해준다..
RMI Multicast를 자동(peerDiscovery=automatic)으로 해주면 동일 네트워크상에서 ehcache 분상 캐싱을 하는 서버중 동일한 multicastGroupAddress를 사용하는 것들을 자동으로 찾아내어 캐싱을 수행한다. 따라서 multicastGroupAddress=230.0.0.1 을 모두 동일하게 맞춰주면 된다.
사실상 각서버의 모든 설정파일에 위 내용을 완전히 동일하게 설정하여 배포하면 모든 분산 캐싱이 자동으로 이뤄진다.
더 자세한 내용은 EhCache Distributed Caching을 참조한다.
Hibernate 연동
자세한 사항은 EhCache Hibernate Caching을 참조한다.
hibernate.properties
- hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.cache.provider_configuration_file_resource_path=/ehcache.xml [ehcache 설정파일의 CLASSPATH 위치]
hibernate.cache.use_query_cache=true
Entity 설정
- @Entity
- @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) // Root Entity에만 영향을 끼친다.
- public class Entity {
- ....
- @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
- @JoinColumn(name="CUST_ID")
- @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) // Sub Entity도 캐시하라고 지정
- private SortedSet<Ticket> tickets;
- }
Query 설정
- criteria.setCacheable(true);
- criteria.setCacheMode(CacheMode.XXX);
- query.setCacheable(true);
- query.setCacheMode(CacheMode.XXX);
단, 분산 캐싱을 쿼리에 대해서 수행할 때 나 같은 경우에는 "org.hibernate.cache.UpdateTimestampsCache"와 "org.hibernate.cache.StandardQueryCache" 캐시를 설정하지 않으면 제대로 분산 캐싱이 이뤄지지 않았다. 정확한 것인지는 모르겠으나 쿼리 결과의 분상 캐싱이 제대로 이뤄지지 않으면 위 캐시설정을 ehcache 설정 파일에 넣고 확인해보기 바란다.
Spring Framework에서 사용하기
Spring 에는 EhCache 인스턴스를 자동으로 생성해주는 팩토리가 있다.
- <bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheName="cache이름 비워둬도됨">
<property name="cacheManager">
<bean
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml" />
</property>
</bean>
