Ответ
Стратегия инвалидации кеша зависит от требований к актуальности данных и характера нагрузки. Вот основные подходы и когда их применять:
1. Инвалидация по времени (TTL - Time to Live)
Используйте, когда данные могут быть "слегка устаревшими" и их обновление предсказуемо.
// Установка ключа с автоматическим истечением через 5 минут
IDatabase cache = connection.GetDatabase();
cache.StringSet("user:profile:123", jsonData, TimeSpan.FromMinutes(5));
Когда применять: Для данных, которые меняются нечасто (профили пользователей, каталоги товаров, статичный контент).
2. Явная (активная) инвалидация
Удаляйте ключ сразу при изменении исходных данных. Это гарантирует консистентность.
// После успешного обновления записи в БД
await _userRepository.UpdateAsync(user);
await cache.KeyDeleteAsync("user:profile:" + user.Id); // Немедленная инвалидация
Когда применять: Для критически важных данных, где устаревшая информация недопустима (баланс счета, статус заказа, актуальная цена).
3. Паттерн "Write-Through" или "Cache-Aside" с инвалидацией
Кеш обновляется синхронно с записью в основное хранилище.
public async Task UpdateProductAsync(Product product)
{
// 1. Обновить базу данных
await _dbContext.SaveChangesAsync();
// 2. Обновить кеш (или удалить, чтобы следующее чтение загрузило свежие данные)
var cacheKey = $"product:{product.Id}";
await _cache.StringSetAsync(cacheKey, JsonSerializer.Serialize(product), TimeSpan.FromHours(1));
}
4. Вытеснение политиками Redis (LRU, LFU)
Redis автоматически удаляет ключи при нехватки памяти, согласно настройке maxmemory-policy (например, allkeys-lru).
Когда полагаться: Это стратегия "последней линии обороны", а не основная. Всегда лучше управлять сроком жизни ключей явно.
Рекомендации:
- Комбинируйте подходы: Используйте TTL как "страховку" даже при явной инвалидации.
- Мониторьте hit rate: Низкий процент попаданий в кеш может указывать на слишком короткий TTL или неэффективные ключи.
- Используйте паттерны: Для сложных сценариев рассмотрите паттерны Cache-Aside, Read-Through или Write-Behind.
Ответ 18+ 🔞
Давай разберём эту тему про кеш, как взрослые люди, без этих ваших заумных терминов, которые только в документациях красиво смотрятся.
Смотри, вся эта история с инвалидацией — это как разобраться, когда тебе холодильник чистить. Можно по расписанию, можно когда вонять начинает, а можно просто жрать всё сразу, пока не испортилось. Выбирай, что тебе ближе.
1. По таймеру (TTL) — "автопилот для ленивых" Ставишь время — и забыл. Ключ сам сдохнет через заданный промежуток. Как молоко в холодильнике с датой истечения.
cache.StringSet("user:profile:123", jsonData, TimeSpan.FromMinutes(5)); // Живёт 5 минут и в пизду
Брать на вооружение, когда: Данные меняются редко, и всем похуй, если они чуть устарели. Каталог товаров, список городов, профиль юзера (ну подумаешь, он аватарку час назад поменял, а ты ещё старую видишь — не умер же никто).
2. Ручная инвалидация — "сам всё контролирую, мать его" Изменились данные в главной базе? Немедленно выковыривай старый кеш. Чтобы следующий запрос поднял свежачок.
await _userRepository.UpdateAsync(user);
await cache.KeyDeleteAsync("user:profile:" + user.Id); // Бдыщ! И нет ключа.
Юзать, когда: Консистентность важнее всего. Финансы (баланс), статусы заказов ("оплачено" или "хуёво"), акционные цены. Здесь просроченные данные — это прямой путь в жопу, причём в самую глубокую.
3. Паттерн "обновил в базе — сразу в кеш засунь" Чуть более продвинутая версия ручного управления. Не просто удалил старьё, а сразу положил новое. Чтобы следующий бедолага, который запросит эти данные, не ходил в базу, а взял уже готовое и свежее.
await _dbContext.SaveChangesAsync(); // В базу записал
var cacheKey = $"product:{product.Id}";
await _cache.StringSetAsync(cacheKey, JsonSerializer.Serialize(product), TimeSpan.FromHours(1)); // И в кеш сразу
4. "А хуй его знает, пусть Redis сам разбирается" (LRU/LFU)
Настраиваешь политику вытеснения в Redis (типа allkeys-lru). Когда память заканчивается, он начинает выкидывать ключи, которые давно не использовались. Это как приходишь на кухню, а там места нет, — начинаешь безжалостно выкидывать старые консервы и пустые банки из-под пива.
На что похоже: На стратегию "последней надежды". Нельзя на это полагаться как на основной метод. Это спасательный круг, когда всё уже хуёво.
Итоговые советы, чтобы не обосраться:
- Страхуйся. Даже если используешь ручную инвалидацию, накидывай TTL. Вдруг твой код удаления ключа ебнулся и не сработал? TTL подстрахует и через час-другой почистит мусор.
- Следи за попаданиями. Смотри на метрику
hit rate. Если она низкая, значит, кеш почти не работает. Возможно, TTL слишком короткий, или ключи составлены криво, или данные вообще не те кешируешь. - Выбирай паттерн по ситуации. Не надо из пушки по воробьям. Если данные не критические — хватит и TTL. Если от актуальности зависит денежный поток — будь добр, инвалидируй вручную и сразу.
Вот и вся философия. Не усложняй там, где не надо, но и не расслабляйся там, где это чревато пиздецом.