Стратегии кэша и инвалидация, cache stampede

↑ 7.1 Производительность .NET и кэширование · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

«В компьютерной науке две сложные вещи: инвалидация кэша и именование». Ждут знания паттернов.

Объяснение

СтратегияКак работаетПлюсы/минусы
Cache-aside (lazy)приложение читает кэш, при промахе грузит из БД и кладёт в кэшпросто, возможны устаревшие данные
Read-throughкэш сам загружает данные при промахеменьше кода в приложении
Write-throughзапись идёт в кэш и БД синхронносогласованность, задержка записи
Write-behindзапись в кэш, БД обновляется асинхронноскорость, риск потери
Refresh-aheadобновление до истечения TTLнет пиков задержки

Инвалидация:

  • TTL: простое и надёжное, допускает устаревание на время TTL.
  • Явное удаление при изменении данных (событием, тегом).
  • Версионирование ключей (product:v12:42): старые ключи «умирают» сами.
  • Событийная: подписка на изменения (CDC, доменные события).

Cache stampede (thundering herd): ключ истёк, тысячи запросов одновременно идут в БД.

ЗащитаИдея
Блокировка на ключ (single flight)один запрос обновляет, остальные ждут (HybridCache)
Jitter TTLслучайный разброс срока жизни
Stale-while-revalidateотдавать устаревшее, обновляя в фоне
Вероятностное раннее обновлениеобновление до истечения с вероятностью
Кэширование «отрицательных» результатовзащита от запросов несуществующих ключей (cache penetration)
var lease = await gate.WaitAsync(ct);             // SemaphoreSlim на ключ
try { if (!cache.TryGetValue(key, out value)) { value = await load(); cache.Set(key, value, ttl + jitter); } }
finally { gate.Release(); }

Нюансы и подводные камни

  • Race в cache-aside: конкурентная запись и удаление могут оставить устаревшее значение; TTL — страховка.
  • Горячие ключи в Redis перегружают один узел: локальный L1.
  • Кэш холодного старта: прогрев после деплоя.
  • Утечка данных между пользователями при неверном ключе.

Практика

  1. Воспроизведите stampede нагрузочным тестом и устраните single flight.
  2. Реализуйте stale-while-revalidate.
  3. Добавьте метрики hit ratio и задержки промахов.

Вопросы с ответами

Связанные темы