Кэширование в C# (.NET): Redis и другие инструменты для ускорения приложений
Кэширование — один из наиболее эффективных способов повысить производительность и масштабируемость приложений на C# (.NET). В этой статье мы подробно разберём встроенные механизмы кэширования, популярные библиотеки для работы с Redis, а также альтернативные решения. Вы узнаете, как правильно выбрать инструмент под свою задачу и избежать типовых ошибок.
Встроенные механизмы кэширования в .NET
Платформа .NET предоставляет несколько готовых решений для кэширования, которые подходят для большинства сценариев без установки сторонних зависимостей.
1. MemoryCache (System.Runtime.Caching)
Встроенный кэш в памяти процесса. Идеален для однопоточных приложений или малых нагрузок. Данные хранятся в оперативной памяти и автоматически удаляются при нехватке ресурсов.
using System.Runtime.Caching;
public class MemoryCacheService
{
private readonly MemoryCache _cache = MemoryCache.Default;
public T GetOrSet<T>(string key, Func<T> factory, int expirationMinutes = 5)
{
var cached = _cache.Get(key);
if (cached != null) return (T)cached;
var result = factory();
var policy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(expirationMinutes)
};
_cache.Set(key, result, policy);
return result;
}
}
2. IDistributedCache (Microsoft.Extensions.Caching)
Абстракция для распределённого кэширования. Позволяет легко переключаться между Redis, SQL Server, NCache и другими провайдерами. Рекомендуется для микросервисов и облачных приложений.
using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;
public class DistributedCacheService
{
private readonly IDistributedCache _cache;
public DistributedCacheService(IDistributedCache cache)
{
_cache = cache;
}
public async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> factory, int expirationMinutes = 10)
{
var cached = await _cache.GetStringAsync(key);
if (cached != null) return JsonSerializer.Deserialize<T>(cached);
var result = await factory();
var options = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(expirationMinutes)
};
await _cache.SetStringAsync(key, JsonSerializer.Serialize(result), options);
return result;
}
}
Redis: король распределённого кэширования
Redis — это высокопроизводительное in-memory хранилище данных, поддерживающее строки, списки, хэши, множества и другие структуры. Для .NET основной библиотекой является StackExchange.Redis.
Установка и настройка StackExchange.Redis
Установите пакет через NuGet:
dotnet add package StackExchange.Redis
Пример подключения и базовых операций:
using StackExchange.Redis;
public class RedisCacheService
{
private readonly ConnectionMultiplexer _redis;
private readonly IDatabase _db;
public RedisCacheService(string connectionString)
{
_redis = ConnectionMultiplexer.Connect(connectionString);
_db = _redis.GetDatabase();
}
public async Task SetAsync(string key, string value, int expirationMinutes = 5)
{
await _db.StringSetAsync(key, value, TimeSpan.FromMinutes(expirationMinutes));
}
public async Task<string> GetAsync(string key)
{
return await _db.StringGetAsync(key);
}
}
Расширенные возможности Redis
- Pub/Sub — уведомления между сервисами
- Sorted Sets — рейтинги и лидерборды
- Lua-скрипты — атомарные операции
- Redis Cluster — горизонтальное масштабирование
Альтернативы Redis: когда выбирать другое?
Несмотря на популярность Redis, существуют ситуации, когда другие решения оказываются более уместными.
| Инструмент | Когда использовать | Недостатки |
|---|---|---|
| MemoryCache | Одно приложение, малые объёмы данных | Не работает при перезапуске процесса |
| SQL Server Cache | Уже есть SQL Server, нужна сохранность | Медленнее Redis, блокировки |
| NCache | Корпоративные решения, .NET Framework | Платная лицензия, сложная настройка |
| Memcached |