Мы любим кеш за ускорение чтения, но любое ускорение — это компромисс. Чаще всего страдает актуальность.
Как говорил Фил Карлтон: «В Computer Science есть только две сложные вещи: инвалидация кеша и придумывание названий».
Инвалидация: Удаление по времени
| Параметр | Как считает время | Когда удалит объект | Где применять |
|---|---|---|---|
| TTL (Time To Live) | С момента создания (SET) | Всегда по истечении таймера, даже если объект активно читают каждую секунду. | Цены, курсы валют, новости на главной. (Нужна гарантированная свежесть). |
| TTI (Time To Idle) | С момента последнего доступа (GET/SET) | Если за указанный интервал к ключу ни разу не обратились. Таймер обнуляется при каждом чтении. | Пользовательские сессии, токены, корзины. (Кеш сам чистится от «брошенного» мусора). |
Шесть стратегий инвалидации
| Стратегия | Где работает лучше всего | Минусы |
|---|---|---|
| TTL / TTI | Чаты, аналитика, сессии | Не годится для критично важных, быстро меняющихся сущностей. |
| Ручная | Админ-панели, CMS | Разработчик может забыть написать в коде. |
| 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