Кэширование в C# (.NET): Redis, MemoryCache и другие решения

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Кэширование в C# (.NET): Redis, MemoryCache и другие инструменты

В современных высоконагруженных приложениях на C# (.NET) кэширование является одним из ключевых механизмов повышения производительности и снижения нагрузки на базы данных. В этой статье мы подробно рассмотрим основные инструменты кэширования в экосистеме .NET: встроенный MemoryCache, распределённый кэш на базе Redis через библиотеку StackExchange.Redis, а также абстракцию IDistributedCache.

1. Встроенное кэширование: MemoryCache

MemoryCache (пространство имён Microsoft.Extensions.Caching.Memory) — это простейший способ кэширования данных прямо в оперативной памяти процесса. Идеально подходит для однопроцессных приложений (например, ASP.NET Core без масштабирования).

Пример базового использования:

using Microsoft.Extensions.Caching.Memory;

// Создание кэша
IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());

// Запись в кэш с временем жизни 5 минут
cache.Set("user:123", new User { Id = 123, Name = "Иван" }, 
    TimeSpan.FromMinutes(5));

// Чтение из кэша
if (cache.TryGetValue("user:123", out User user))
{
    Console.WriteLine($"Пользователь: {user.Name}");
}
else
{
    Console.WriteLine("Кэш пуст, загружаем из БД...");
}

Преимущества: максимальная скорость, нулевая задержка сети, простота настройки.
Недостатки: данные живут только в одном процессе, теряются при перезапуске приложения.

2. Распределённое кэширование: Redis + StackExchange.Redis

Для распределённых систем (несколько серверов, микросервисы) необходим внешний кэш. Redis — самый популярный выбор. Основная библиотека для работы с Redis в .NET — StackExchange.Redis (более 6 тысяч звёзд на GitHub).

Установка:

dotnet add package StackExchange.Redis

Пример работы с Redis:

using StackExchange.Redis;

// Подключение к Redis
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = redis.GetDatabase();

// Запись строки с TTL (время жизни)
db.StringSet("session:token123", "user_data_here", TimeSpan.FromHours(1));

// Чтение
string data = db.StringGet("session:token123");
if (!string.IsNullOrEmpty(data))
{
    Console.WriteLine($"Данные из кэша: {data}");
}

// Кэширование сложных объектов (сериализация в JSON)
var product = new Product { Id = 1, Name = "Ноутбук", Price = 75000 };
string json = System.Text.Json.JsonSerializer.Serialize(product);
db.StringSet("product:1", json, TimeSpan.FromMinutes(10));

// Десериализация при чтении
string cachedJson = db.StringGet("product:1");
var cachedProduct = System.Text.Json.JsonSerializer.Deserialize<Product>(cachedJson);

Дополнительные возможности Redis:

  • Хэши (Hashes) — для хранения объектов с полями (например, профиль пользователя).
  • Списки и множества — для очередей, рейтингов.
  • Pub/Sub — для уведомлений об инвалидации кэша.
  • Lua-скрипты — атомарные операции.

3. Абстракция IDistributedCache

Microsoft предоставляет интерфейс IDistributedCache (пакет Microsoft.Extensions.Caching.Abstractions), который позволяет переключаться между различными реализациями кэша без изменения кода приложения.

Реализации:

  • MemoryDistributedCache — для разработки и тестов (хранит в памяти).
  • RedisCache (пакет Microsoft.Extensions.Caching.StackExchangeRedis) — для продакшена.
  • SqlServerCache — для кэширования в SQL Server (редко используется).

Пример в ASP.NET Core:

// В Program.cs
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "MyAppCache";
});

// Использование в сервисе
public class ProductService
{
    private readonly IDistributedCache _cache;

    public ProductService(IDistributedCache cache)
    {
        _cache = cache;
    }

    public async Task<Product> GetProductAsync(int id)
    {
        string key = $"product:{id}";
        string cached = await _cache.GetStringAsync(key);

        if (cached != null)
            return JsonSerializer.Deserialize<Product>(c                    

Рекомендаций