I can get items out of the cache manager by using
cachemanager.getCache("cachename").get(cacheKey)
How do I add a new cache via the cache manager? There appears to be only getCache() and getCacheNames().
There is getCache("newcachename").put(cacheKey) but that fails as "newcachename" doesn't exist.
Sorted, my fault. I didnt add the new cache details to the ehcache.xml file.
<cache name="newcachename" maxElementsInMemory="10000"
eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="300"
overflowToDisk="false" diskPersistent="false"/>
Once I added this I could use
getCache("newcachename").put(cacheKey, "value to cache")
Thanks all for your assistance.
I don't know exactly what you configuration looks like so I can't give a more detailed explanation, but I have successfully used multiple caches using Spring's CompositeCacheManager
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="newcachename" />
</set>
Have you set up this cache for this cacheName in the configurations?
Related
We have spring based(3.2.9.Release) java web application and use hibernate for db operations.
We currently have caching mechanism using Dynacache which is configured through WebSphere server and use jndi mapping. We retrieve all the content from database on first page load and store it in Dynacache. Since it is a external call every time, we wanted to implement Eh-Cache and improve the performance. But surprisingly the performance of Eh-Cache is lesser than Dynacache and takes long time to load the page. Below is the configuration we had for Eh-Cache:
xml configuration:
<bean id="cacheService" class="com.wlp.sales.ols.core.api.cache.CacheService"></bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="/WEB-INF/configs/EhCache/ehcache.xml" />
<property name="shared" value="true" />
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<cache name="contentCache"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="true"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="0" timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
dependencies:
<!-- ehCache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
We have a cache implementation class which will generate cache key using get and put methods to retrieve from db and put into a cache map as key value pair.
public Object get(CdiRequest request) {
Object cdiObject = cacheService.get(request.getContentElement()
.getContentType(), keyBuilder.build(request));
return cdiObject instanceof CdiResponse ? (CdiResponse) cdiObject
: request;
}
//Put method implementation:
cacheService.put(cdiResponse.getCdiRequest().getContentElement()
.getContentType(),
keyBuilder.build(cdiResponse.getCdiRequest()), cdiResponse);
Implementation class :
public class CacheService implements ApplicationContextAware{
#Autowired
private CacheManager cacheManager;
private ApplicationContext applicationContext;
public Object get(String applnName, Object key) {
Cache cache = cacheManager.getCache("contentCache");
return cache.get(key);
}
public boolean put(String applnName, Object key, Object value) {
Cache cache = cacheManager.getCache("contentCache");
cache.put(key, value);
return true;
}
}
It takes almost 60 seconds to 80 seconds to load each page on refresh or reload whereas dynacache just takes 3-4 seconds. Please advise if anything is being done wrongly or could done in a better way.
Why you don't want to provide standard annotations for Cache in Spring, and use it in the method that is obtaining values from DB?:
#Cacheable(value="contentCache", key="#name")
So you can get your content from DB and store in cache? If something changes, you can use CacheEvict.
There are several things that can be improved:
At the configuration level
Do you really need the disk store? It adds overhead as content must be serialized / deserialized.
In case you need it, you need size the disk store bigger than the onheap one, as all mapping will exist in the disk store. So with the current configuration, you are effectively limiting the onheap size to 1000.
At the usage level, you are effectively using the cache as an in memory store because you have no logic to handle the case where the mapping is not found. Now, maybe what you are caching is a known set of keys and smaller than the size you have set. Still, this might be a later cause of problems.
With regards to the performance concerns, you will need to provide more detailed information if you need help tracking what is the issue.
In Ehcache, to remove old entries I have enabled timeToIdleSecondsproperty.
Periodically, one process tries to remove all the expired elements from cache by calling cache.evictExpiredElements()
Cache Configuration:
<cache name="cache" maxEntriesLocalHeap="100000" eternal="false" overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="60"/>
The following exception thrown during eviction (not always):
EhCache: run(): catching java.lang.NullPointerException at net.sf.ehcache.store.offheap.disk.OffHeapDiskStore.expireElements(OffHeapDiskStore.java:348)
~[ehcache-ee-2.9.0.jar:2.9.0] at
net.sf.ehcache.store.CacheStore.expireElements(CacheStore.java:426)
~[ehcache-ee-2.9.0.jar:2.9.0] at
net.sf.ehcache.Cache.evictExpiredElements(Cache.java:2986)
~[ehcache-ee-2.9.0.jar:2.9.0]
Am I missing something here?
I am using ehcache in ditributed mode .
The caches are synchronized by channel .
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="channelName=CHANNEL1:connect=UDP(mcast_port=45568)"
propertySeparator=":" />
For a new requirement , i need to synch with two channels : CHANNEL1 and CHANNEL2 .
Is this possible ? if yes , how i can do that ?
Thanks in advance
Usually One instance of cacheManagerPeerProviderFactory is used to replicate ( or Synchronize) number of caches across cluster. In that case, "channelName=CHANNEL1:" is more like simply giving a name. I don't think ehCache supports multiple channels.
If you're requirement is to have some replication specific one channel, you can try one of the following
Run two EhCache Managers in the same application each with it's ehcache.xml, One for the specific replication logic, and one for the common replication logic of caches.
You will have only one cache manager, but your ehcache.xml will vary in a way that, you won't include the cache ( which requires specific replication logic) with in the third application.
First one is more cleaner approach.
You can have multiple EhcacheManagers with Spring in following way,
<ehcache:annotation-driven cache-manager="ehCacheManager1" />
<bean id="ehCacheManager1" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache-1.xml" />
</bean>
<bean id="ehCacheManager2" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache-2.xml" />
</bean>
is there a way i can take away the configuration of infinispan completely from the standalone.xml and have the configuration like the following in my persistence.xml :
<property name="hibernate.cache.infinispan.entity.strategy" value= "LRU" />
<property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "1000"/>
<property name="hibernate.cache.infinispan.entity.eviction.strategy" value= "LRU"/>
<property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval" value= "2000"/>
<property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "5000"/>
<property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "60000"/>
<property name="hibernate.cache.infinispan.entity.expiration.max_idle" value= "30000"/>
thanks in advance
I don't know your use case but there is a possibility to configure Infinispan CacheManagers and Caches programmatically using fluent builder API. It means no need of standalone.xml and even no need of configuration for Infinispan in persistence.xml.
For more information see: https://docs.jboss.org/author/display/ISPN/Configuring+cache+programmatically
In this tutorial I can see configuration of CacheManager like this (which can be confusing now):
EmbeddedCacheManager manager = new DefaultCacheManager("my-config-file.xml");
You can configure it entirely programmatically too without any input xml file, for example:
GlobalConfigurationBuilder global = new GlobalConfigurationBuilder();
global.transport().defaultTransport();
global.globalJmxStatistics().enable();
manager = new DefaultCacheManager(global.build());
I want to place property place holders in the ehcache.xml file (like ${}) so that the values can be replaced from external properties file (.properties) at runtime.
Something like:
ehcache.xml (in classpath):
<defaultCache
maxElementsInMemory="20000"
eternal="false"
timeToIdleSeconds="${default_TTI}"
timeToLiveSeconds="86400"
overflowToDisk="true"
... />
ehcache.properties (outside of the war/classpath):
...
default_TTI=21600
...
The purpose is to be able to change the cache configuration without the need to rebuild the app. Spring's PropertyPlaceHolder will only work with Spring bean definiton for ehcache which I dont want (need to keep the ehcache.xml as a file)
There are similar posts here but nothing got me to solution. I've been searching for a week now!!
Im using Spring 2.5.6,Hibernate 3.2.6 and Ehcache 2.4.6
Any help or idea is greatly Appriciated!!
Thanks a lot,
Tripti.
As a workaroud solution you can set property values to system scope (System.setProperty(...)). EhCahe uses these properties to resolve placeholders during parsing its configuration file.
I got the solution finally! Thanks to braveterry for pointing me in that direction.
I used this at context startup:
Inputstream = new FileInputStream(new File("src/config/ehcache.xml").getAbsolutePath());
cacheManager = CacheManager.create(stream);
in conjuction with hibernate configuration:
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
This creates a singleton CacheManager from ehcache.xml file outside the context classpath. I was doing this same earlier but was accidently creating another CacheManager before this one using the default ehcache.xml in the classpath.
Thanks,
Tripti.
svaor, I follow what you mean, I define a bean like this:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System" />
<property name="targetMethod" value="setProperty" />
<property name="arguments">
<list>
<value>system.project_name</value>
<value>${system.project_name}</value>
</list>
</property>
</bean>
system.project_name define in system.properties file which locate in classpath
I also create a ehcache.xml in classpath, in ehcache.xml has the code like this:
<diskStore path="${java.io.tmpdir}/${system.project_name}/cache" />
but when I deploy my project, I find it cann't use the system.project_name define in system.properties, why?
If you just want to read the config in from disk at startup, you can do the following in EHCache 2.5:
InputStream fis =
new FileInputStream(new File("src/config/ehcache.xml").getAbsolutePath());
try
{
CacheManager manager = new CacheManager(fis);
}
finally
{
fis.close();
}