Инвалидация и замещение

Мы любим кеш за ускорение чтения, но любое ускорение — это компромисс. Чаще всего страдает актуальность.

Как говорил Фил Карлтон: «В Computer Science есть только две сложные вещи: инвалидация кеша и придумывание названий».

Инвалидация: Удаление по времени
Параметр Как считает время Когда удалит объект Где применять
TTL (Time To Live) С момента создания (SET) Всегда по истечении таймера, даже если объект активно читают каждую секунду. Цены, курсы валют, новости на главной. (Нужна гарантированная свежесть).
TTI (Time To Idle) С момента последнего доступа (GET/SET) Если за указанный интервал к ключу ни разу не обратились. Таймер обнуляется при каждом чтении. Пользовательские сессии, токены, корзины. (Кеш сам чистится от «брошенного» мусора).
Шесть стратегий инвалидации
Стратегия Где работает лучше всего Минусы
TTL / TTI Чаты, аналитика, сессии Не годится для критично важных, быстро меняющихся сущностей.
Ручная Админ-панели, CMS Разработчик может забыть написать cache.del(key) в коде.
Event-based Микросервисы (через Kafka/RabbitMQ) Сложная инфраструктура, нужен брокер.
Versioned Keys Мультирегиональные API (ключ вида user:123:v2) Накапливается старый «мусор», нужна фоновая очистка.
Замещение

Что произойдет, если память в Redis закончится? Возможны два сценария: либо база начнет отклонять новые записи с ошибкой (OOM), либо начнет вытеснять (Eviction) старые данные, чтобы освободить место.

Разберем варианты вытеснения. Или, как еще говорят, замещения данных в кеше.

Алгоритм Основная идея Подводные камни
LRU (Least Recently Used) Удаляет «самый давно не использованный» ключ. Стандарт де-факто. Но при массовом сканировании БД может вытеснить реально полезные данные.
LFU (Least Frequently Used) Считает обращения. Удаляет то, что читают реже всего. Сложнее и требует больше памяти на счетчики. Может «залипать» на устаревших трендах.
FIFO (First-In First-Out) Удаляет то, что добавили самым первым. Игнорирует частоту использования. Вытеснит горячий ключ просто потому, что он старый.

Давай рассмотрим пример LRU