2
votes

We use the replicated Tomcat web-server setup with two nodes. We use Ehcache as Hibernate level 2 cache provider for our web application. So we configured Ehcache setup through RMI replication as described in official docs: http://ehcache.org/documentation/user-guide/rmi-replicated-caching.

We use now timeToLiveSeconds parameter for cache entries, and wanted to switch to timeToIdleSeconds as it seems to be more effective. But then we came accross this (http://ehcache.org/documentation/user-guide/cache-topologies):

Use of Time To Idle

Time To Idle is inconsistent with replicated caching. Time-to-idle makes some entries live longer on some nodes than in others because of cache usage patterns. However, the cache entry "last touched" timestamp is not replicated across nodes. Do not use Time To Idle with replicated caching, unless you do not care about inconsistent data across nodes.

What do they mean "inconsistent data across nodes" - will you see different data if you access different nodes? But how could this happen? So if user works with one node - he constantly accesses some entries - they stay in cache of that node because of TTI. At the same time the same entries may expire on second node's cache. But won't they just be re-fetched from Database when accessed on second node? And what's the principal difference from TTL in this aspect?

1

1 Answers

2
votes

Each SessionFactory resides on one node with its own 2nd-level cache.

The idle time is dependent on the current node request patterns and because the last access time is not replicated you may end up with an old entity version on a node and a refreshed one on the other.

While Hibernate can detect entity changes when using HQL or JPQL, it cannot do that for queries, hence it just invalidates all 2nd-level cache regions. So, this use case is real and plausible.

It's very difficult to maintain strict consistency when you do caching over a distributed system, that's why it's best to resort to it when all other options are already exhausted.