Кэширование в 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