August 5, 2020
In today’s high-performance web applications, caching plays a critical role in reducing latency and improving response times. Distributed caching is particularly useful for applications that scale horizontally, where multiple instances of the application need access to a shared cache. One of the most popular caching solutions in the .NET ecosystem is Redis.
In this post, we will explore how to set up Redis with .NET Core and use it for distributed caching, focusing on session state and frequently accessed data. Redis is an open-source, in-memory data store that supports different data structures like strings, hashes, lists, and more, making it a great option for caching.
1. What is Redis and Why Use It?
Redis is an in-memory data structure store, often used as a cache or message broker. It’s incredibly fast and supports a variety of data types, making it a great choice for caching scenarios.
Using Redis as a distributed cache in a .NET Core application allows data to be shared across different application instances. Redis can store session state, frequently accessed data, or any other type of data that benefits from being cached in memory for faster retrieval.
2. Setting Up Redis in .NET Core
a. Installing Redis
Before we can use Redis in a .NET Core application, we need to install and configure Redis on our machine or use a cloud service like Redis Labs or Azure Redis Cache.
To install Redis locally:
- On macOS, use Homebrew:
brew install redis
- On Linux, follow the official Redis installation guide.
- For Windows, you can use the Windows Subsystem for Linux (WSL) or use Redis from Docker.
Once installed, start Redis using the command:
redis-server
For cloud Redis, simply create an instance and obtain the connection details (hostname, port, password).
b. Install Redis NuGet Package
In your .NET Core project, you will need to install the StackExchange.Redis NuGet package, which is the most popular Redis client for .NET.
Run the following command in your terminal or Package Manager Console:
dotnet add package StackExchange.Redis
3. Setting Up Redis in the Application
Now that Redis is installed, let’s configure the connection in your .NET Core application. We’ll set up Redis as a distributed cache using the IDistributedCache interface.
a. Configure Redis in Startup.cs
In the Startup.cs
file, we will configure Redis in the ConfigureServices method. First, add the Redis connection string (hostname and port) in your appsettings.json
file:
{
"RedisConnection": "localhost:6379"
}
Next, modify Startup.cs
to configure Redis:
public void ConfigureServices(IServiceCollection services)
{
// Configuring Redis as Distributed Cache
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetValue<string>("RedisConnection");
options.InstanceName = "SampleApp_";
});
services.AddControllers();
}
This code configures the StackExchange.Redis client to use the Redis instance at localhost:6379
. The InstanceName
is used to prefix keys in Redis, which can be useful for managing cache namespaces.
4. Using Redis for Distributed Caching
With Redis configured, we can now use it in our controllers or services to cache data. We’ll use IDistributedCache for interactions with Redis.
a. Storing Data in Redis
Let’s cache some data, such as a user’s session or an API response, using SetStringAsync:
public class CacheController : ControllerBase
{
private readonly IDistributedCache _cache;
public CacheController(IDistributedCache cache)
{
_cache = cache;
}
[HttpGet("cache-example")]
public async Task<IActionResult> CacheExample()
{
string key = "user_123";
string value = "John Doe";
// Storing data in Redis
await _cache.SetStringAsync(key, value, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) // Cache for 5 minutes
});
return Ok($"Data cached for {key}");
}
}
In this example, we store the string “John Doe” associated with the key user_123
in Redis. We also specify an expiration time for the cache, ensuring it will be removed after 5 minutes.
b. Retrieving Data from Redis
Now, let’s retrieve the cached data:
[HttpGet("get-cache-example")]
public async Task<IActionResult> GetCacheExample()
{
string key = "user_123";
// Retrieving data from Redis
string value = await _cache.GetStringAsync(key);
if (value == null)
{
return NotFound("Cache miss: No data found.");
}
return Ok($"Cached data: {value}");
}
Here, we attempt to retrieve the data associated with the key user_123
. If the key doesn’t exist in the cache, it will return a cache miss (i.e., the data has expired or was never cached).
c. Removing Data from Redis
To remove data from Redis, use RemoveAsync:
[HttpGet("remove-cache-example")]
public async Task<IActionResult> RemoveCacheExample()
{
string key = "user_123";
// Removing data from Redis
await _cache.RemoveAsync(key);
return Ok($"Data removed for {key}");
}
This method removes the specified key-value pair from Redis, ensuring that the data is no longer available.
5. Using Redis for Session State
One of the most common use cases for distributed caching is to store session data, especially for web applications that scale horizontally across multiple servers. Redis is a great fit for this.
To use Redis for session state:
- Install the Microsoft.AspNetCore.Session NuGet package:
dotnet add package Microsoft.AspNetCore.Session
- In
Startup.cs
, enable sessions and configure Redis as the session store:
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.Configuration = Configuration.GetValue<string>("RedisConnection");
options.InstanceName = "Session_";
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20); // Session timeout
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app)
{
app.UseSession(); // Enable session middleware
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
- Use sessions in your controllers:
[HttpGet("set-session")]
public IActionResult SetSession()
{
HttpContext.Session.SetString("username", "John Doe");
return Ok("Session data set.");
}
[HttpGet("get-session")]
public IActionResult GetSession()
{
string username = HttpContext.Session.GetString("username");
if (username == null)
{
return NotFound("Session data not found.");
}
return Ok($"Session username: {username}");
}
This setup allows you to store session data in Redis, enabling your application to scale across multiple instances without losing session state.
6. Conclusion
Using Redis for distributed caching in .NET Core is a powerful way to improve the performance and scalability of your application. By caching frequently accessed data and storing session state in Redis, you can significantly reduce the load on your databases and make your application more responsive.
Redis offers low-latency, high-throughput performance, making it an excellent choice for caching scenarios in large-scale distributed systems.
With StackExchange.Redis and the IDistributedCache interface, integrating Redis with your .NET Core application is straightforward. Whether you’re using Redis for caching API responses or storing session data, Redis will help your application scale more efficiently.