Click here to Skip to main content
15,885,757 members
Articles / Programming Languages / C#

Implementing Local MemoryCache Invalidation with Redis

Rate me:
Please Sign up or sign in to vote.
4.92/5 (5 votes)
1 Jan 2014CPOL4 min read 32.8K   7   4
How to implement local MemoryCache Invalidation with Redis

We need to use all the tools at our disposal to develop faster and more robust applications. One of the ways we can achieve this is by using caching. Previously, under the System.Web.Caching.Cache namespace, the new -4.0- System.Runtime.Caching.Memory is more mature and still as powerful as its ancestor. It’s really easy to use and I think that every ASP.NET programmer has already used it. So, I won’t speak too much about this here.

The default caching strategy is the cache-aside programming pattern: This means that if your data is not present in the cache, your application, and not something else, you must reload data into the cache from the original data source.

This works very well for most common use cases, but there is a hidden trade-off: caching means working with stale data. Should I increase the cache duration? Should I keep short TTL value? It’s never easy to answer to these questions, because it simply depends on your context: number of clients, user load, database activity…

Another common problem is how to update/remove instantly something from the cache on all your cache clients, such as this typical request from Product Owner ” I want a parameter to be instantly updated on all our XXX servers, but do not fear, I will only change it a few times per year.”

I will investigate a not so new concept in this post: setup local cache invalidation using Redis.

What is Local Cache Invalidation?

Cache invalidation is a process whereby entries in a cache are removed/deleted. This concept is not specific to .NET, but to all technologies. The idea here is to send invalidation message to each server and not wait –as usual- item expiration.

Why Redis?

Redis is an open-source, networked, in-memory, key-value data store with optional durability. (Note familiar? Read the great documentation here). It’s now the most popular NoSql database, and many internet leaders are using it (Instagram, Stackoverflow, Twitter, GitHub, Tumblr, Pinterest, …). For the joke, nothing will be stored in Redis, and we will only use the PubSub feature.

And yes, since I discovered Redis, I’m a big fan. :)

Implementation

Requires : .NET, Redis & Booksleeve (high perf C# redis client).

The concept is quite handy: Redis events (pub/sub) give us an easy way to broadcast something to all nodes (lossely coupled), so they can drop their local copy – meaning: next time it is needed, we’ll pick up the new copy from the data tier.

So, the redis pub/sub events are used to invalidate the cache for a given key from one node (the one that knows the state has changed) immediately to all nodes. A node could be a front web site, a back app or any redis client.

Local cache invalidation is done with ChangeMonitor class : “Provides a base class for a derived custom type that monitors changes in the state of the data which a cache item depends on”. It’s the base class of FileChangeMonitor and SqlChangeMonitor.

redisinvalidation

A few details:

  • A single connection is opened to redis, as BookSleeve is a thread-safe multiplexer.
  • As there is a single connection to redis and possibly many monitors, I use a topic-based observer pattern to manage notification inside the application.
  • I send only invalidation message following this format: channel = “invalidate”, and message = “keytoremove”.

Here is a possible implementation in an ASP.NET application.

  • Redis Configuration Configuration
    C#
    // somewhere in your global.asax (for an asp.net application)
    // be sure a redis instance is running on localhost
    // check /tools/redis-server.exe
    CacheInvalidation.UseRedis(new RedisConnectionInfo() {
         Host = "localhost"
    });
  • How to create a redis changemonitor
    C#
    // somewhere in your code
    var cacheItem = new CacheItem("onekey", "onevalue");
    var policy = new CacheItemPolicy();
    policy.ChangeMonitors.Add(CacheInvalidation.CreateChangeMonitor(cacheItem));
    // just to create not expirable item
    policy.AbsoluteExpiration = DateTime.Now.AddYears(1);
    MemoryCache.Default.Add(cacheItem, policy);

Various Benefits

  • Not limited to .NET, and any Redis client could invalidate cache item on subscribers
  • Multi-Memory Cache support and not only the default
  • Supports out-of-process invalidation
  • Fully compatible with existing applications, as the invalidation is done by a separate piece of code, in another thread in ASP.NET
  • Allows you to invalidate a list of items
  • Redis connection unavailable?
    • Temporary failure: Not a problem as the bus will try to reconnect automatically
    • Redis server not available: No-op, and your application will run without any problems

Knowing how to invalidate will not resolve all your problems. :)

“There are only two hard problems in Computer Science: cache invalidation and naming things.”, Phil Karlton.

Further Considerations …

What about combining local cache invalidation with an out-of-Process caching system?

There is where things gets interesting: Keep the best of the two worlds and implement a 2-tier cache – i.e., using local memory and the out-of-process cache (distributed).

This is well explained by Marc Gravell, creator of BookSleeve:

“Going off to another system is never faster than querying local memory (as long as it is keyed); (@Stackoverflow) we use both!”

Finally, this also a funny way to introduce Redis in a non-critical scenario. So do not hesitate.

The GitHub Repo is available here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer Betclic
France France
I am Head of Software Development at Betclic France. I manage the Paris Dev Team, consisting of 35+ talented people, in various technical and functional projects in the fields of sports betting, poker, casino or horse betting.

Check out our technical blog at https://techblog.betclicgroup.com
This is a Organisation

3 members

Comments and Discussions

 
QuestionStateless load balancing Pin
Andy Lippitt14-Nov-14 11:16
Andy Lippitt14-Nov-14 11:16 
QuestionWhy subscribe does'nt received publish message? Pin
roy166913-Apr-14 22:30
roy166913-Apr-14 22:30 
AnswerRe: Why subscribe does'nt received publish message? Pin
Cybermaxs19-Nov-14 8:21
Cybermaxs19-Nov-14 8:21 
QuestionVery good article! Pin
Volynsky Alex1-Jan-14 8:51
professionalVolynsky Alex1-Jan-14 8:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.