Caches of all versions of a webapp deployed in parallel are shutdowned - java

I use ehcache in a webapp whose versions are deployed in parallel on a Tomcat instance. This is a handy way to deploy new versions without stopping an application.
I however have a problem with this way to proceed : even if I give the cache and disk store different names, depending on the versions of the webapp, all caches are stopped when stopping one instance.
My config is :
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" name="mywebapp-${project.version}_build_${buildNumber}">
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000"
eternal="false"
timeToLiveSeconds="300"
timeToIdleSeconds="300"
overflowToDisk="true"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
statistics="true"
/>
<cache
maxElementsInMemory="1000"
maxElementsOnDisk="10000"
name="org.hibernate.cache.internal.StandardQueryCache"
eternal="false"
timeToLiveSeconds="300"
timeToIdleSeconds="300"
overflowToDisk="true"
diskPersistent="false"
statistics="true"/>
<cache
name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
timeToLiveSeconds="300"
timeToIdleSeconds="300"
eternal="false"
overflowToDisk="true"
diskPersistent="false"
statistics="true"/>
<cache
name="query.Presences"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
eternal="false"
timeToLiveSeconds="300"
timeToIdleSeconds="300"
overflowToDisk="true"
diskPersistent="false"
statistics="true"/>
<diskStore path="java.io.tmpdir/mywebapp-${project.version}_build_${buildNumber}"/>
</ehcache>
${project.version} and ${buildNumber}
being replaced by maven during the build process.
Does someone know how to avoid this unwanted behaviour ?
I am using ehcache-core-2.4.3 and hibernate-ehcache-4.3.8.

The way net.sf.ehcache.constructs.web.ShutdownListener works is by shutting down ALL cache managers.
So the only way for this to work for you is by making sure your cache managers end up in different class loaders, that is ehcache is loaded by the web application class loader and not the container one.
Do you provide ehcache jar in your app's WEB-INF/lib? If yes, are you sure there is not an Ehcache in tomcat's classpath?
If this solution still does not work, you may be better off creating your own ServletContextListener that would shutdown only the cache manager from the containing application.

Some details are missing from your query.
1)How are you stopping the cache?
2)How are you deploying application in tomcat?
3)Have you checked the location where does the cache object is created ?
But as a behavior all cache will cleared once you restart tomcat.

Related

ehcache "maxBytesLocalHeap" not overflowing objects to disk

I am using the following ehcache(2.9.0 version) config for caching around 2 GB of data.
In this config maxBytesLocalHeap is not getting honored. Objects are not overflowing to disk. I tried to test the config by setting maxBytesLocalHeap="1M".
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<diskStore path="c:\\cache" />
<cache
name="cache1"
maxBytesLocalHeap="1M"
maxBytesLocalDisk="5G"
overflowToDisk="true"
diskPersistent="true" />
<cache
name="cache2"
maxBytesLocalHeap="1M"
maxBytesLocalDisk="5G"
eternal="true"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1"
memoryStoreEvictionPolicy="LFU"/>
</ehcache>
I am getting the cache instance as follows :
CacheManager cm = CacheManager.newInstance();
Cache cache = cm.getCache("cache1");
Cache cacheTrade = cm.getCache("cache2");
Have i missed any config?

Replicated Caching using RMI EhCache data is not loading in all Tomcat instances

I am trying to implement EhCache Replicated Caching using RMI. I have a Spring Web application wich uses EhCache for data caching. Ehcache holds few Java.Util.Map, that is used through out the application view pages. When a record (say some business JAVA POJO object) is created by the user from front end screen, that record will be inserted into the database and subsequently, Maps held by the EhCache is updated.
Later, we deployed this web application in 3 tomcat instances in the same machine. Application is accessible via the Apache HTTP Load Balancer.
Promblem I am facing is, EhCache data is loading on one tomcat instance. But not on other two. When the application is individually accessed with port numbers, the application is running fine.
Same Spring web application runs on Tomcat instances (9001, 9002, 9003). EhCache RMI configured to listen (4001, 4002, 4003).
Please find the ehCache.xml files that I configured,
On Tomcat Instance 1
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=10.237.31.33, port=40001, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//10.237.31.33:40002/widgets|//10.237.31.33:40002/lobCache|//10.237.31.33:40002/lobFilterCache|//10.237.31.33:40002/glossarylobFilterCache|//10.237.31.33:40002/bbpUserListCache|//10.237.31.33:40002/userRoleCache|//10.237.31.33:40002/glossary|//10.237.31.33:40003/widgets|//10.237.31.33:40003/lobCache|//10.237.31.33:40003/lobFilterCache|//10.237.31.33:40003/glossarylobFilterCache|//10.237.31.33:40003/bbpUserListCache|//10.237.31.33:40003/userRoleCache|//10.237.31.33:40003/glossary" />
<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />
On Tomcat Instance 2
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=10.237.31.33, port=40002, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//10.237.31.33:40001/widgets|//10.237.31.33:40001/lobCache|//10.237.31.33:40001/lobFilterCache|//10.237.31.33:40001/glossarylobFilterCache|//10.237.31.33:40001/bbpUserListCache|//10.237.31.33:40001/userRoleCache|//10.237.31.33:40001/glossary|//10.237.31.33:40003/widgets|//10.237.31.33:40003/lobCache|//10.237.31.33:40003/lobFilterCache|//10.237.31.33:40003/glossarylobFilterCache|//10.237.31.33:40003/bbpUserListCache|//10.237.31.33:40003/userRoleCache|//10.237.31.33:40003/glossary" />
<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />
On Tomcat Instance 3
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="WidgetCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=10.237.31.33, port=40003, socketTimeoutMillis=2000" />
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//10.237.31.33:40001/widgets|//10.237.31.33:40001/lobCache|//10.237.31.33:40001/lobFilterCache|//10.237.31.33:40001/glossarylobFilterCache|//10.237.31.33:40001/bbpUserListCache|//10.237.31.33:40001/userRoleCache|//10.237.31.33:40001/glossary|//10.237.31.33:40002/widgets|//10.237.31.33:40002/lobCache|//10.237.31.33:40002/lobFilterCache|//10.237.31.33:40002/glossarylobFilterCache|//10.237.31.33:40002/bbpUserListCache|//10.237.31.33:40002/userRoleCache|//10.237.31.33:40002/glossary" />
<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<diskStore path="java.io.tmpdir" />
Kindly advise what I am missing here.
The below is configured in spring-servlet.xml
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:ehcache.xml" p:shared="true"/>
And from the Java business class
public class PortfolioUserDetailsServiceImpl implements PortfolioUserDetailsService {
private Logger logger = LoggerFactory
.getLogger(PortfolioUserDetailsServiceImpl.class);
private UserDao userDao;
#Autowired
private CacheManager cacheManager;
private Ehcache userRoleCache;
#PostConstruct
public void init() {
// Load our widgets cache:
userRoleCache = cacheManager.getEhcache("userRoleCache");
// Create an EHCache Element to hold the widget
Element element = new Element("getAllRoles", userDao.getAllRoles());
// Add the element to the cache
userRoleCache.put(element);
}
I am getting NullPointerException on the following method
#Override
public List<BbpUser> loadUsersfromUserListCache() throws InventoryException {
// TODO Auto-generated method stub
Cache cache = cacheManager.getCache("userRoleCache");
Element elementt = cache.get("getAllRoles");
return (List<BbpUser>) elementt.getObjectValue();
}
when replicateUpdatesViaCopy is set to false, entry will be removed from caches on other instances. You need to check for null and load it from the datastore (or whereever you have the latest value).
You can set replicateUpdatesViaCopy to true and check if you are still getting NPE on accessing other instances.
For complete details, you can go through http://www.ehcache.org/generated/2.10.0/html/ehc-all/index.html#page/Ehcache_Documentation_Set/co-rmi_configuring_cache_replicators.html

How to have permanent cache using ehcache in spring mvc

I want to use ehcache in my spring mvc web application.because my server reset every day so i want caching be permanent. do i save it in hard path? and hoe save it?
thanks.
in my dispatcher-servlet.xml i add this
<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="classpath:ehcache.xml"/>
<property name="shared" value="true"/>
</bean>
and my ehcach.xml is
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="c:/tmp"/>
<defaultCache
maxElementsInMemory="500" eternal="true" overflowToDisk="false" memoryStoreEvictionPolicy="LFU"/>
<cache name="mycache"
maxElementsInMemory="0"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1200"
memoryStoreEvictionPolicy="LRU">
[1] <persistence strategy="localRestartable" synchronousWrites="false" />
</cache>
i add this [1] until caching be permanent and after server reset not be remove.but this exception occur Element does not allow nested elements.
also i use ehcach-core2.7.0.jar
Element <cache> does not allow nested <persistence> elements.
You should not mix legacy configuration options - attributes diskPersistent and overflowToDisk on the cache element with recommended persistence element.
However, to get to the open source disk persistent setting, you need to stick with the legacy options.
So your configuration should drop the persistence element to become:
<cache name="mycache"
maxElementsInMemory="0"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1200"
memoryStoreEvictionPolicy="LRU">
</cache>
However, you should also give a meaningful value to maxElementsInMemory, so you can have a hot set of entries for which you do not need to pay the deserialization price when accessing them.
You also need to decide if you want eternal elements or have expiration. For this, remove either eternal="true" or the timeToLiveSeconds and timeToIdleSeconds pair. Having both is not an error in Ehcache for compatibility reasons, but makes it hard to know what you intended initially.
And as a last advice, I would move the cache content to a folder with a more descriptive name instead of c:/tmp.
Note that the open source disk persistent tier is not fault tolerant, so improper shutdown of the Cache or CacheManager or exceptions while doing IO can corrupt the data. If that happens, you will have to clear the data folder before you can restart your cache.
For more details, see the Ehcache 2.7 persistence documentation.
Have you tried this?
<cache eternal="true"
maxElementsInMemory="0"
name="<cache name>"
overflowToDisk="true"/>

Problem defaultCache and cache in distributed environment (Inconsistent data)

Using the same configuration, with only defaultCache, I get inconsistent data (case A). But if I add an additional cache entry will not get those errors of inconsistency (case B).
Do you know why?
I do not want to set the 130 caches that set aumaticamente defaultCache
Thanks in advance
P. S. I guess all the time that what is not specified, will EHCache as a template using defaultCache settings.
Case A:
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
overflowToDisk="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
/>
<bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</defaultCache>
`
Case B:
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
overflowToDisk="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
/>
<bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</defaultCache>
<cache
name="com.liferay.portal.model.impl.LayoutImpl"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
overflowToDisk="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
/>
<bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
</cache>
Since you haven't said how to you use cache it's hard to guess what you are really doing and what errors of inconsistency do you mean.
Maybe you are not caching query results with cached entities, which makes entities to be read from cache and queries from database? There are many possible cases.
We tried to run Liferay on the cluster env and got the same error: default config doesn't work.
I made some changes, maybe my config will help you.
hibernate-clustered.xml
liferay-multi-vm-clustered.xml

ehcache memorystoresize and diskstoresize

[Avatar]
2010-09-23 18:20:41 IST
I have the following configuration for my ehcache.
<CacheManager dynamicConfig="true" monitoring="autodetect" name="CacheManager1"
updateCheck="true"> <diskStore path="java.io.tmpdir" /> <defaultCache
clearOnFlush="true" copyOnRead="false" copyOnWrite="false" diskAccessStripes="1"
diskExpiryThreadIntervalSeconds="5" diskPersistent="true" diskSpoolBufferSizeMB="20"
eternal="true" logging="true" maxElementsInMemory="100" maxElementsOnDisk="100"
memoryStoreEvictionPolicy="LRU" name="cache1" overflowToDisk="true" statistics="true"
timeToIdleSeconds="0" timeToLiveSeconds="60" transactionalMode="off"> </defaultCache>
<cache clearOnFlush="true" copyOnRead="false" copyOnWrite="false" diskAccessStripes="1"
diskExpiryThreadIntervalSeconds="5" diskPersistent="true" diskSpoolBufferSizeMB="20"
eternal="true" logging="true" maxElementsInMemory="100" maxElementsOnDisk="100"
memoryStoreEvictionPolicy="LRU" name="cache1" overflowToDisk="true" statistics="true"
timeToIdleSeconds="0" timeToLiveSeconds="60" transactionalMode="off"> </cache>
</CacheManager>
The maxElementsInMemoryStore and maxElementsOnDiskStore are set to 100. I have put 150 elements in the cache. When i query for the MemoryStoreSize and the DiskStoreSize i get 138 and 15. I could not understand the sizes returned. Can someone please explain why is it so??
I found the reason for MemoryStoreSize > maxElementsInMemory here. When the size of the MemoryStore has been exceeded, further calls to put() will cause the extra elements to be pushed to an overflow (disk spool) queue, which is flushed to disk asynchronously using a worker thread. The disk spool queue is 300MB by default, and only gets flushed when full (or at shutdown, if the cache is persistent).
The call to get MemoryStoreSize returns the sum of the elements in the MemoryStore and in the disk spool queue.
Some elements may be in the queue and on disk at the same time, which explains why the two numbers do not sum to 150.
Some entries can be both in memory and on disk so adding them up will not give you the total.

Categories