On this page

Skip to content

Implementing Distributed Caching with Redis in ASP.NET

TLDR

  • For Windows environments, it is not recommended to use the archived Microsoft Redis version; using WSL 2, Docker, or Memurai is recommended instead.
  • When deploying Redis using Docker, if you encounter connection refused errors, you need to adjust the bind and protected-mode settings in redis.conf.
  • For single-server environments, IMemoryCache is recommended as its performance is superior to distributed caching.
  • IDistributedCache natively supports string access only; it is recommended to extend the API based on project requirements.
  • When using IDistributedCache, if data is subject to change, be sure to use AbsoluteExpiration or IChangeToken strategies.

Since Redis does not natively support Windows, please avoid using the discontinued Microsoft archived version when developing in a Windows environment. The following alternatives are recommended:

  • WSL 2: The officially recommended installation method via the Linux compatibility layer.
  • Memurai: A native Windows port compatible with Redis 6.2, suitable for development and testing environments.
  • Docker: Deployed via the official image, suitable for cross-platform consistency requirements.

Notes on Installing Redis Using Docker

When does this occur: When deploying Redis using Docker and external applications cannot connect to the container.

If custom configuration is required, mount redis.conf and specify it via command. If you encounter a "Connection refused" error, check and modify redis.conf:

  • Comment out bind 127.0.0.1 -::1.
  • Change protected-mode yes to protected-mode no.

TIP

The bind parameter limits the IPs allowed to connect; if set to 127.0.0.1, only local connections are permitted. If protected-mode is set to yes, you must configure bind or a requirepass password authentication.

Using MemoryCache in ASP.NET Core

When does this occur: When the application is deployed on a single server and has extremely high performance requirements.

IMemoryCache provides two expiration strategies:

  • Absolute: Absolute expiration time; the item is removed once the time is reached.
  • Sliding: Sliding expiration time; the survival time is extended if the item is continuously accessed.

WARNING

If cached data is subject to change, it is recommended to use AbsoluteExpiration or IChangeToken to ensure data consistency.

Implementing Distributed Caching with Redis in ASP.NET Core

When does this occur: When the application is deployed across multiple servers (distributed architecture) and needs to share cache state.

By using the Microsoft.Extensions.Caching.StackExchangeRedis package, you can inject IDistributedCache into your project:

csharp
builder.Services.AddStackExchangeRedisCache(options => {
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
    options.InstanceName = "SampleInstance";
});

WARNING

If there is only one App Server, IMemoryCache performs better than IDistributedCache because the latter involves remote network access. Furthermore, IDistributedCache natively supports string access only; it is recommended to extend the API yourself for complex objects.

Using Redis in ASP.NET Framework

When does this occur: When maintaining legacy .NET Framework (e.g., 4.8) projects.

You can use the StackExchange.Redis package directly, and it is recommended to manage ConnectionMultiplexer using the Singleton pattern:

csharp
public sealed class RedisConnection {
    private static readonly Lazy<RedisConnection> lazy = new Lazy<RedisConnection>(() => new RedisConnection());

    private RedisConnection() {
        ConnectionMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1:6379");
    }

    public static RedisConnection Instance => lazy.Value;
    public ConnectionMultiplexer ConnectionMultiplexer { get; }
}

Usage:

csharp
IDatabase db = RedisConnection.Instance.ConnectionMultiplexer.GetDatabase(0);
string cachedValue = await db.StringGetAsync("CacheKey");

Change Log

  • 2022-11-02 Initial documentation created.