Reputation: 45
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 multiple, that is, 3 tomcat instances. Application is accessible via the Apache HTTP Load Balancer.
Problem we are facing is, when user inserts a record into the database, EhCache is updated only in the application that run on a tomcat instance which got the request. As we have 3 tomcat instances, the application running on other 2 tomcat instances does not have updated EhCache data. This affects the user from viewing the updated data immediately from the screen.
Could anyone please advise how to resolve this issue. How to sync the EhCache data between the Spring web application that run on multiple tomcat instances.
FYKI, this is my first web application in my career and begineer towards the Data Caching concepts.
PLEASE ADVISE ME THE METHODS OF SOLVING THIS ISSUE?
Let me share how I configured the EhCache in my spring web application as simple,
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);
}
@PreDestroy
public void destory() {
logger.info("INVENTORYSERVICEIMPL destroy method called");
}
Here is my ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="PortfolioCache" updateCheck="false">
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache name="userRoleCache" maxElementsInMemory="100" eternal="false"
timeToIdleSeconds="0" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
</cache>
<diskStore path="java.io.tmpdir" />
</ehcache>
Upvotes: 1
Views: 3047
Reputation: 14500
Your main issue when having multiple application servers is with regards to cache consistency.
When a cache entry is updated in tomcat 1, the update needs to be propagated to the other servers.
In this case you can indeed go for clustered Ehcache. I would not recommend a replicated cache because it will still expose a window of inconsistency. And of course other caching providers offer clustering options.
Upvotes: 0
Reputation: 153
I think the Best Method is a using "Terracotta Distributed Ehcache" you can refer to following links :
http://terracotta.org/documentation/enterprise-ehcache/get-started http://ehcache.org/documentation/2.6/get-started/about-distributed-cache
Upvotes: 0