We are running a cluster of 30+ servers with massive caching to improve our performance. We use Spring Boot. We have
- hibernate 2LC replicated with invalidation mode
- Local Application Caches without any clustering
- and Application Caches with invalidation mode.
We used EhCache 2.x with JGroups Replication before. It was configured with
replicatePuts=false
This sets "whether new elements placed in a cache are replicated to others.". See https://www.ehcache.org/documentation/2.8/replication/jgroups-replicated-caching.html#example-configuration-using-udp-multicast
Now we switched to Infinispan 13.x.
Hibernate is easy as Infinispan configures everything just fine. It uses putForExternalRead
under the hood if the key is not already in the cache. For our Local Application Caches, which are not replicated, everything works fine, too.
We had problems with our Application Caches in Invalidation mode. These are configured like this:
embeddedCacheManager.defineConfiguration(NAME,
new ConfigurationBuilder()
.memory()
.maxCount(10000)
.whenFull(EvictionStrategy.REMOVE)
.statistics()
.enabled(true)
.expiration()
.maxIdle(-1)
.lifespan(-1)
.clustering()
.cacheMode(CacheMode.INVALIDATION_ASYNC)
.build());
When we put a new Object into the cache with
cache.put(key, value)
This put results in an invalidation message to the cluster and all other nodes remove this key from the cache.
Of course, we found out, that we can use the following method instead:
cache.putForExternalRead(key, value)
This has many drawbacks:
- We can't use Spring Cache abstraction anymore as Spring doesn't support it
- On each cache operation the developer must check if it is a replicated cache
- On each cache operation the developer must check if it is a new object or if the key is already in the cache
It would be nice to configure some caches to use always putForExternalRead under the hood if a new element is put into the cache. Something like
.clustering()
.cacheMode(CacheMode.INVALIDATION_ASYNC)
.replicatePuts(false)
Is it possible to achieve this? Is it possible to use an interceptor or listener to avoid sending the invalidation message on new object?
for me it makes so much sense the way ehcache is doing it. I am wondering if I misunderstood something or if infinspan just can't handle this situation.