Ответ
Двухуровневый кэш — это паттерн, при котором система кэширования состоит из двух уровней: быстрого, но малого по объёму кэша первого уровня (L1) и более медленного, но ёмкого кэша второго уровня (L2). Цель — минимизировать задержки при доступе к данным и снизить нагрузку на основное хранилище (например, БД).
Типичная реализация в веб-приложении:
- L1 (In-Memory Cache): Быстрый кэш в памяти процесса приложения (например,
IMemoryCacheв .NET). - L2 (Distributed Cache): Распределённый кэш, доступный нескольким экземплярам приложения (например, Redis).
Пример кода на C#:
public class TwoLevelCacheService
{
private readonly IMemoryCache _memoryCache; // L1
private readonly IDistributedCache _distributedCache; // L2
private readonly IDataSource _primarySource; // БД или внешний API
public async Task<string> GetDataAsync(string key)
{
// 1. Проверяем L1
if (_memoryCache.TryGetValue(key, out string cachedData))
{
return cachedData;
}
// 2. Проверяем L2
var data = await _distributedCache.GetStringAsync(key);
if (data != null)
{
// Обновляем L1 для будущих быстрых запросов
_memoryCache.Set(key, data, TimeSpan.FromMinutes(1));
return data;
}
// 3. Обращаемся к первичному источнику (промах в кэшах)
data = await _primarySource.FetchDataAsync(key);
// 4. Заполняем оба уровня кэша
await _distributedCache.SetStringAsync(key, data, new DistributedCacheEntryOptions {
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
});
_memoryCache.Set(key, data, TimeSpan.FromMinutes(5));
return data;
}
}
Преимущества и недостатки:
| Преимущество | Недостаток |
|---|---|
| Снижение задержки: Частые запросы обслуживаются из быстрого L1. | Сложность согласованности: Необходима стратегия инвалидации данных в обоих кэшах. |
| Уменьшение нагрузки на L2 и БД: L1 поглощает часть трафика. | Дополнительные издержки: Усложнение кода и инфраструктуры. |
| Масштабируемость: L2 (распределённый) обеспечивает консистентность между нодами. | Риск устаревших данных: При неправильной TTL данные в L1 могут быть stale. |