Problem defaultCache and cache in distributed environment (Inconsistent data) - java

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

Related

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.

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

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?

Incorrect ehcache statistics: hits+misses == 0

I have a problem where net.sf.ehcache.CacheManager appears returns invalid statistics.
I'm using ehcache-core v2.3.2 (latest version) with ehcache-spring-annotations.
The problem is that getMemoryStoreObjectCount returns 1 object while both getCacheHits and getCacheMisses returns 0. Isn't the total count supposed to be hits + misses ?
The unit test below should illustrate the problem (it's applied to an empty database):
#Test
public void testCache() {
Entity e = ..
dao.storeEntity(e);
dao.getEntity(e);
assertEquals(1, cache.getStatistics().getMemoryStoreObjectCount()); // ok
assertEquals(0, cache.getStatistics().getCacheHits()); // ok
assertEquals(1, cache.getStatistics().getCacheMisses()); // fails due to 0
}
For completeness I include all essential configuration:
Spring config
<ehcache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
ehcache.xml
<ehcache>
<defaultCache eternal="false" maxElementsInMemory="1000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
</ehcache>
dao
#Cacheable(keyGenerator=#KeyGenerator(name="StringCacheKeyGenerator"))
public Entity getEntity(Serializable key) {
return // sql ...
}
Add statistics="true" to your ehcache.xml, it's usually better to keep your configuration changes outside your code.
<ehcache>
<defaultCache ... statistics="true" />
...
</ehcache>
Found the solution to the problem by setting the following properties in net.sf.ehcache.hibernate.EhCache:
cache.setStatisticsEnabled(true);
cache.setStatisticsAccuracy(Statistics.STATISTICS_ACCURACY_GUARANTEED);
The <defaultCache ... statistics="true" /> works greatly
in contrast with the old way cache.setStatisticsEnabled(true); that needs the lower version of ehcache (core and etc).

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