Using Redis Cache in .NET Core

Redis is a high performance distributed cache. It’s great for storing data that you are going to need again and again in a short period of time when you don’t want to use processing power to “create” that data again. Think number crunching or heavy SQL queries for data that doesn’t change often.

Roll Your Own

First off. You can absolutely roll your own Redis Cache services abstracted by your own interfaces etc. You may find it a little difficult to find libraries that target .NET Core, but this will change over time.

In saying that, there is a “.NET core” way of doing things that is a little different. It does tie you into the framework a little, but it abstracts away the caching completely and let’s Microsoft handle it and that’s what we are going to go over today.

The ASP.NET Core Way

The first thing you need to do is add the Redis caching package provided by Microsoft. You can do this in your package manager console by running :

Install-Package Microsoft.Extensions.Caching.Redis

In your startup.cs, you now need to add the following to your ConfigureServices method. It should look something like :

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();

	services.AddDistributedRedisCache(option =>
	{
		option.Configuration = "127.0.0.1";
		option.InstanceName = "master";
	});
}

For your Configuration, while I’ve hardcoded this to 127.0.0.1, you can obviously change this to pull from your configuration as required. Either from AppSettings/ConnectionStrings etc.

And as you can probably guess with the method signature of “AddDistributedRedisCache”, you can also use things like SQL or InMemory caches using a similar sort of method. We will go over this in future posts!

AddDistributedRedisCache actually adds an interface automagically to your service collection called “IDistributedCache” that you can then use to set and retrieve values. You can then use controller dependency injection to get this anywhere in your app. So say we have a controller called HomeController and it wants to use the RedisCache. It would go :

[Route("api/[controller]")]
public class HomeController : Controller
{
	private readonly IDistributedCache _distributedCache;

	public HomeController(IDistributedCache distributedCache)
	{
		_distributedCache = distributedCache;
	}

	[HttpGet]
	public async Task<string> Get()
	{
		var cacheKey = "TheTime";
		var existingTime = _distributedCache.GetString(cacheKey);
		if (!string.IsNullOrEmpty(existingTime))
		{
			return "Fetched from cache : " + existingTime;
		}
		else
		{
			existingTime = DateTime.UtcNow.ToString();
			_distributedCache.SetString(cacheKey, existingTime);
			return "Added to cache : " + existingTime;
		}
	}
}

The first time we view this page, there is nothing in the cache so we are given a new time. And it’s added to the cache. If we refresh the page, we then end up with the time that was cached. So for example :

Added to cache : 5/01/2017 1:27:24 AM
*refresh page a few seconds later*
Fetched from cache : 5/01/2017 1:27:24 AM

A couple more notes.

  • IDistributedCache has async methods. You should use these in all scenarios that are possible.
  • IDistributedCache allows for storing either string values or byte values. If you want to serialize an object and store the entire thing, you can either serialize it to bytes and save it as bytes, or serialize it to JSON and save it as a string if you prefer.
  • As discussed earlier, while this is a Redis distributed cache, there are other implementations available that follow the exact pattern for InMemory, SQL Server etc.

If you need to use an InMemory Cache rather than Redis, see our tutorial on In Memory Caching here

8 thoughts on “Using Redis Cache in .NET Core”

  1. Hello !
    Good tutorial. Fast and efficient.
    One question: How to configure a connection to Redis server using a Unix socket, instead of ‘IP’ ?

    Reply
  2. I tried but I am getting this error

    It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. AuthenticationFailure on PING

    Reply
    • You can actually! It’s called the “Keys” command in Redis : https://redis.io/commands/keys

      Note that some libraries don’t allow you to make this call, for good reason. It’s incredibly expensive and not what Redis was made for. It’s really only supposed to be used to debug (e.g. check what keys are currently in the database to debug a particular error), but not to be run constantly.

      There are other ways like using Scan (https://redis.io/commands/scan), but again, I really would advise against using Redis like this.

      Reply
  3. Sync methods should be renamed to async ones like:
    _distributedCache.GetString(cacheKey) should be await _distributedCache.GetStringAsync(cacheKey); and
    _distributedCache.SetString(cacheKey, existingTime); should be await _distributedCache.SetStringAsync(cacheKey, existingTime);

    Reply

Leave a Comment