Выбор политики вытеснения в Redis при нехватке памяти зависит от того, какие данные критичны для бизнеса и как часто они запрашиваются. Если потеря данных допустима, используйте алгоритмы LRU или LFU для удаления наименее важных записей. Если целостность данных обязательна, настройте политику возврата ошибок или вытеснения только просроченных ключей. Ошибка выбора приводит к падению производительности, потере сессий пользователей или сбоям в работе приложений.

Основные принципы работы политик вытеснения

Redis использует политики вытеснения только при включенной опции `maxmemory-policy`. Без неё сервер работает в режиме `noeviction` и отклоняет все записи, превышающий лимит памяти. Это защищает данные, но может остановить приложение.

Алгоритмы выбора ключей для удаления строятся на двух метриках: времени жизни (TTL) и частоте использования. Политики с суффиксом `volatile` работают только с данными, у которых установлен TTL. Политики с префиксом `allkeys` анализируют все ключи независимо от наличия таймера.

Выбор стратегии зависит от типа хранимых данных: кэш сессий, результаты вычислений или постоянные записи базы данных. Для каждого типа подходят разные подходы.

Политика allkeys-lru

Эта стратегия удаляет наименее используемые ключи среди всех данных в памяти, если память заполнена. Алгоритм отслеживает количество обращений к каждому ключу и при нехватке места выбирает те, к которым обращались реже всего.

Подходит для сценариев, где данные однородны по важности или когда важно сохранять только самые активные записи. Например, в кэше API-ответов часто запрашиваемые эндпоинты должны оставаться в памяти, а старые или редкие — удаляться.

Ограничение: алгоритм требует дополнительного хранения метрик использования, что немного увеличивает потребление памяти на каждый ключ. В системах с миллионами мелких ключей это может быть критично.

Политика volatile-lru

Удаляет наименее используемые ключи только среди тех, у которых есть время жизни (TTL). Ключи без таймера остаются в памяти до полного заполнения лимита.

Идеально для кэшей сессий пользователей или временных данных, где наличие TTL является обязательным условием. Если сессия просрочена по времени, она всё равно может быть удалена раньше из-за низкой активности.

Риск: если в системе есть много ключей без TTL (например, постоянные справочники), они будут защищены от вытеснения даже при острой нехватке памяти, что может привести к переполнению памяти.

Политика noeviction

При исчерпании памяти сервер возвращает ошибку `OOM command not allowed when using memory: 'noeviction'` и не удаляет ни одного ключа. Все новые записи отклоняются.

Используется, когда потеря данных недопустима. Подходит для систем учёта, финансовых транзакций или баз данных, где данные должны сохраняться до явного удаления или перезагрузки.

Недостаток: приложение должно уметь обрабатывать ошибки записи и либо откладывать операцию, либо удалять старые данные на стороне клиента перед новой попыткой.

Политика allkeys-random

Удаляет случайные ключи при нехватке памяти. Алгоритм не анализирует статистику использования, а просто выбирает ключи для удаления произвольно.

Применяется как компромисс, когда нет ресурсов на отслеживание метрик LRU/LFU. Гарантирует освобождение места, но может удалить важные данные случайно.

Рекомендуется только в тестовых средах или при отсутствии возможности внедрить более умные алгоритмы.

Политика volatile-random

Удаляет случайные ключи только среди тех, у которых есть время жизни (TTL). Ключи без таймера остаются в памяти.

Подходит для кэшей сессий, где важно не терять данные до истечения их срока действия. Случайный выбор снижает вероятность удаления часто используемых данных по сравнению с LRU.

Политика volatile-ttl

Удаляет ключи, у которых истекло время жизни (TTL), независимо от частоты использования. Если таких ключей недостаточно для освобождения места, политика возвращает ошибку.

Эффективна для кэшей с фиксированным сроком действия. Гарантирует, что данные не будут храниться дольше заданного времени, но может оставить в памяти много старых данных без TTL.

Политика allkeys-lfu

Удаляет наименее часто используемые ключи среди всех данных на основе частоты обращений. LFU (Least Frequently Used) считается более точным, чем LRU, так как учитывает реальную популярность данных.

Подходит для сценариев, где важна не только свежесть данных, но и их актуальность. Например, в кэше товаров часто покупаемые позиции должны оставаться в памяти дольше редких.

Политика volatile-lfu

Удаляет наименее часто используемые ключи только среди тех, у которых есть время жизни (TTL). Сочетает преимущества LFU и фильтрации по TTL.

Идеально для кэшей сессий или временных данных, где важно сохранять активные записи и не хранить просроченные. Требует больше памяти для хранения счётчиков частоты использования.

Как оценить результат и выбрать стратегию

Определите тип данных: если данные временные (сессии, кэш вычислений), используйте `volatile-*`. Если данные постоянные или критичные — `noeviction` или `allkeys-random`.

Проанализируйте паттерны доступа: если часто запрашиваемые данные должны оставаться в памяти, выбирайте LRU или LFU. Если важна только свежесть данных — TTL-политики.

Учитывайте нагрузку на память метрик: политики LRU/LFU требуют дополнительного места для хранения статистики. При ограниченной памяти это может быть проблемой.

Практические примеры настройки

Для кэша сессий пользователей установите `maxmemory-policy volatile-lru`. Это обеспечит удаление неактивных сессий при заполнении памяти.

Для базы данных результатов вычислений используйте `allkeys-lfu`, чтобы сохранять часто используемые результаты и удалять редко запрашиваемые.

Если данные критичны, настройте `noeviction` и добавьте логику в приложении для очистки старых записей перед новой попыткой записи.

Ошибки при выборе политики

Использование `allkeys-lru` для данных с TTL: это приводит к двойному вытеснению — ключи удаляются как из-за низкой активности, так и по истечении срока действия.

Выбор `noeviction` без обработки ошибок в приложении: приложение падает при попытке записи, что нарушает доступность сервиса.

Игнорирование метрик памяти: политики LRU/LFU потребляют больше памяти на хранение статистики. При малом лимите это может привести к переполнению.

Как проверить текущую политику

Используйте команду `CONFIG GET maxmemory-policy` для просмотра текущей настройки.

Проверьте статистику вытеснений через `INFO stats`, где показаны количество удалённых ключей по каждой причине.

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

Можно ли комбинировать несколько политик вытеснения?

Нет, Redis поддерживает только одну политику на уровне сервера. Однако можно разделить данные по разным базам или использовать разные ключевые пространства с разными стратегиями очистки на стороне приложения.

Как избежать случайного удаления важных данных при использовании allkeys-random?

Используйте `volatile-random` для временных данных и `allkeys-lfu` для постоянных. Если критичны данные без TTL, настройте `noeviction` и добавляйте логику очистки в приложении.

Почему LRU может быть менее точным, чем LFU?

LRU удаляет наименее используемые ключи за последний период времени, что не учитывает долгосрочную популярность. LFU учитывает общую частоту обращений, что лучше подходит для данных с неравномерным паттерном доступа.

По теме