• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Devaka Cooray
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Saloon Keepers:
  • Tim Holloway
Bartenders:

Redis cache consistency: how do you deal with it?

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Redis is quite popular in Java, spring itself provides quite easy abstraction for caching using redis. You just apply an annotation @Cacheable or use programmatic approach cache.get(..). There is also an option for cache.evict to remove stale entries and load new ones. And basically this is it when talking about redis. There is not much being talked about keeping the cache eventually consistent.

With redis and horizontal scaling, many app instances can try to load entries and evict them at once. So for example, instance A loads an entry. It takes some time due to /reasons/. Meanwhile instance B starts loading and it goes fast. Newer B value lands in cache but is overriden by older A value.

OR

cache A is loading value to cache. Meanwhile instance B evicts the value. Then cache A saves the value in cache. Cache ends up with stale value, there is no /eventuality/ in consistency here.

My approach is to use redis locks and some fancy eviction registry to allow for not blocking eviction when other process is loading the value. But I am surprised that there is so little being talked about this problem. At first hand it seems that there is no difference between in-memory and externalised cache.

How do you deal with this problem? Any out of the box solutions?

 
Saloon Keeper
Posts: 29002
214
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is common for cache to be a multi-level feature. For example, on a CPU system, you might have 1 level for the CPU register file (primary). a second-level cache onboard the CPU chip itself, a third level being an external chipset between CPU and address bus, then of course primary RAM, which itself may be backed up to persistent storage. Names, implementations and locations can vary depending on the system.

For something like what you describe, I'd expect that you'd have the option to do more or less in-memory caching backed by more or less bulk (disk) caching with the possibility of balancing off in-application memory caching versus in-memory caching in a system like redis where caching might me applied to several apps, especially if it's an elastic server.

I can't speak to the specifics of redis, but I use squid and two of the tuning parameters I give it are the size ranges of the files squid will cache and the total RAM it can use for cache before it spills to disk. All I can say is read the docs. It's what I do. Especially since anything I've last updated more than 6 months ago probably has important changes that should be studied.

Finally, just for completeness I should note that some systems might have more than one type of cached data. For example, static page content for a webserver and database entity data for its ORM system (such as JPA). The backing cache processors for these two different types of data might or might not be the same, depending on system design and the specific abilities of the cache manager.
 
Pater Diuda
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for reply.
I might have been misunderstood. I am talking about the data inconsistency that might occur.
in memory caches like caffeine have some locks to prevent cache stampede or several loads overwriting themselves.
But as redis is an external process, there is no locking. So different instances of an app might overwrite each other entries or loose some data.

Instance A is loading a value. Meanwhile it gets changed and instance B is sending invalidate event.
After that, instance A finishes loading a value. Now we have old value in cache and new value in DB.

Do you hand craft a solution for this everytime? Why is Spring not trying to warn users. it is just "use cacheable and you are fine"
 
Tim Holloway
Saloon Keeper
Posts: 29002
214
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you're going to run multiple processes that each have local caches and they are backed by redis, then your processes would have to post notifications to redis to let it know about the changes.

Like so:

Consider 2 processes, process A and process B. Each has its own local (RAM) cache and each is persistently cached by redis.

Change item X (with key K) in process A. Process A needs to post a change notice for key K to redis. Thus, when B needs the object with key K and goes to fetch it from cache, the cache needs to check with redis for a change notification and if one is found, either signal an alert or cause redis to pull the latest value from process A and make it available to process B.

By default, I'm expecting that you might get the alert, which in the case of Spring might be an OptimisticLockingException.

For best results, then, your cache accesses should probably be Transactional and set the cache and transaction options as appropriate. In the case of Spring JPA, I can say that the default would be for Spring to do Optimistic Locking, as it's less overhead than the pessimistic form. While it has been too long for me to remember the details, I can assure you that if you don't behave yourself it will thump you soundly.
 
Check your pockets for water buffalo. You might need to use this tiny ad until locate a water buffalo:
Paul Wheaton's 16th Kickstarter: Gardening playing cards for gardeners and homesteaders
https://coderanch.com/t/889615/Paul-Wheaton-Kickstarter-Gardening-playing
reply
    Bookmark Topic Watch Topic
  • New Topic