Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refreshing Caches while under load with Spring/EHCache

I have a caching issue on a Spring multi-threaded web service with a database backend and EHCache-based caching. The service has many clients all requesting the same object again and again, with dozens of requests per seconds. There is only a couple of objects that are requested that frequently, with a large number of other objects being requested infrequently. The objects can change every couple of minutes, so the cache's TTL is set to a minute. Loading an object from the database is slow and takes at least several seconds.

At first I used a naive implementation to get the object:

  1. Check whether the object is in the cache.
  2. If yes, return it from the cache.
  3. If not, load it from the database, put it in the cache and return it.

This was working well when initially testing it locally. But performance testing on a faster server showed some pretty bad load spikes every time one of the more frequently requested objects expires in the cache. When this happens, for the next 10 seconds all requests for that object would result in database loads, until the first thread finished the database load and put the new object into the cache. The result was a short but very high load on the database, and a lot of users who need to wait for the request to finish.

My current implementation improves the database load by tracking whether which object are currently being loaded:

  1. Check whether the object is cached.
  2. If yes, return it from the cache.
  3. If not, check whether the object is currently being loaded.
  4. If yes, wait for the other thread's load to complete, get the new object from the cache and return it.
  5. If no, put the object into the list of loading objects, put it into the cache when finished and return it.

With this implementation, even when the object expires, there is only one database operation. And, because of the lower database load, it will also finish sooner. But it still means that all users who request the object during the object load need to wait.

What I would really want is that only the first thread waits for the database load, and all others just return the 'expired' object while the object is being loaded. Response time is more important for me than the fact that the object is a few seconds too old.

Alternatively I could refresh the cache asynchronously when I notice that an object will expire in a few seconds. That's closer to EHCache's single TTL model and would mean that no one needs to wait for the database load

My real question is: before I re-invent the wheel, is there any existing framework that already implements something like this (in a Spring/EHCache environment)? Or maybe support for this already exists somewhere in Spring/EHCache and I just can't find the right option?

like image 770
Tim Jansen Avatar asked Apr 29 '26 06:04

Tim Jansen


1 Answers

There are two Ehcache provided constructs that could help you:

  1. Refresh ahead
  2. Scheduled refresh

Both require you to change the way you interact with your cache as they require a CacheLoader to be configured.

Unfortunately, I can't find online documentation that shows example for the second option. It allows to refresh cache entries using Quartz to schedule it. It can also refresh only a subset of the keys, based on a key generator. Have a look at classes in package net.sf.ehcache.constructs.scheduledrefresh

like image 90
Louis Jacomet Avatar answered Apr 30 '26 19:04

Louis Jacomet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!