ehcache memorystoresize and diskstoresize - java

[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.

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?

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

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.

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"/>

hibernate cached query not updated when new record inserted

We have a EHCache cluster, hibernate and Mysql.
Everything is working almost fine. Criteria searches are being cached and when records are modified on other members of the clusters the cached queries are updated instantly on the other servers.
however, my problem is when new records are inserted. The cached queries on that table do not know about it until the cached query are expired.
I probably have missed something on my EHcache.xml configuration, but I have no idea what could it be.
Any ideas?
EHCache.xml follows:
`
<!--<diskStore path="java.io.tmpdir"/>-->
<!-- means for cache replication -->
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="connect=
TCP(bind_port=10700):
S3_PING(...):
MERGE2(max_interval=30000;min_interval=10000):
FD_SOCK(start_port=0):
FD(timeout=3000;max_tries=3):
VERIFY_SUSPECT(timeout=1500):
BARRIER():
pbcast.NAKACK(use_mcast_xmit=false;gc_lag=0;retransmit_timeout=300,600,1200,2400,4800;discard_delivered_msgs=true):
UNICAST(timeout=300,600,1200):
pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=400K):
pbcast.GMS(print_local_addr=true;join_timeout=300;view_bundling=true):
FC(max_credits=2M;min_threshold=0.10):
FRAG2(frag_size=60K):
pbcast.STREAMING_STATE_TRANSFER()"
propertySeparator="::" />
<!-- default query cache to be used for all queries without an explicit cache -->
<cache
name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="100"
eternal="false"
timeToLiveSeconds="600"
overflowToDisk="false"
statistics="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<!-- timestamps of particular last update time to tables -->
<cache
name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>
<!-- default cache to use for all cacheable entities without an explicit cache -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="600"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="600"
memoryStoreEvictionPolicy="LRU"
statistics="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</defaultCache>
`
I'm afraid it's a little too late for the author, but I thought my answer can be useful for anyone else with the same problem.
You should remember how the StandardQueryCache and the UpdateTimestampsCache work. When the query cache is checked for a query, the time the query was cached is compared to the timestamps of the last update of all tables in the query. If any tables were updated after the query was cached, the cached result gets discarded and the database is used instead. Timestamps of the last update for each table are stored in the UpdateTimestampsCache.
In the above configuration the values from the UpdateTimestampsCache are not copied to other members of the cluster, so Hibernate looks at the old timestamps and thinks that a cached query is up-to-date. As a result newly inserted records are neglected. To fix it simply set replicateUpdatesViaCopy for the UpdateTimestampsCache to true.
Reference: Ehcache configuration
Note that the eternal attribute, when set to "true", overrides timeToLive and timeToIdle so that no expiration can take place.
You have 1 eternal attribute setting to true. Maybe you can try setting it to false and see if it helps?

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

Categories