Руководство по выбору эффективных политик вытеснения Redis

Выберите политику вытеснения Redis, соответствующую вашей нагрузке кэша, сессий или смешанной нагрузке, и настройте maxmemory без потери критических ключей.

Руководство по выбору эффективных политик вытеснения Redis

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

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


Понимание вытеснения Redis и maxmemory

Политики вытеснения вступают в силу только тогда, когда использование памяти Redis превышает лимит, установленный директивой конфигурации maxmemory. Если maxmemory не установлен или установлен в 0, Redis не применяет лимит памяти для обычных записей. На выделенном хосте это может со временем привести к давлению на память операционной системы, поэтому в производственных развертываниях кэша обычно устанавливают явный лимит.

Чтобы включить вытеснение, необходимо настроить maxmemory в файле redis.conf или с помощью команды CONFIG SET:

# Установить maxmemory в 2 ГБ
CONFIG SET maxmemory 2gb

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

Встроенные политики вытеснения Redis

Redis предлагает несколько различных политик. Они настраиваются с помощью директивы maxmemory-policy. Политики обычно делятся на две категории: основанные на наименее недавно использованных (LRU) или наименее часто используемых (LFU), и те, которые нацелены на ключи с установленным временем жизни (TTL).

1. Политики без требований к TTL

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

noeviction

Это политика по умолчанию. Когда лимит памяти достигнут, Redis отклоняет команды записи (например, SET, LPUSH и т.д.), возвращая ошибку клиенту. Чтения (GET) все еще разрешены. Это часто подходит для критически важных данных, где потеря данных недопустима, но может привести к ошибкам приложения при высокой нагрузке на запись.

allkeys-lru

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

allkeys-lfu

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

allkeys-random

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

2. Политики, требующие TTL (изменяемые ключи)

Эти политики учитывают только ключи, у которых установлено явное время истечения (EXPIRE или SETEX). Они игнорируют ключи без срока истечения при выполнении вытеснения.

volatile-lru

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

volatile-lfu

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

volatile-random

Удаляет случайный ключ среди тех, у которых установлен срок истечения.

volatile-ttl

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


Выбор правильной политики для вашей нагрузки

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

Тип нагрузки Рекомендуемая политика Обоснование
Универсальный кэш (наиболее распространенный) allkeys-lru Предполагает, что старые, неиспользуемые данные должны быть удалены в первую очередь, независимо от TTL. Просто и очень эффективно.
Данные, чувствительные ко времени (например, токены, короткоживущие сессии) volatile-ttl Предпочтительно удаляет ключи с наименьшим оставшимся TTL.
Кэш горячих данных (высокий перекос доступа) allkeys-lfu или volatile-lfu Защищает часто запрашиваемые элементы от удаления из-за недавней неактивности.
Обязательное сохранение данных (потеря не допускается) noeviction Предотвращает потерю данных, вызывая ошибки при записи, требуя ручного вмешательства или обработки на стороне вышестоящего приложения.
Смешанные нагрузки (некоторые данные истекают, некоторые нет) volatile-lru, volatile-lfu или volatile-ttl Если ваши ключи без срока истечения являются важными, используйте изменяемую политику, чтобы защитить их, удаляя только ключи с явным сроком истечения.

Практический пример: Реализация хранилища сессий

Если Redis используется в основном для хранения пользовательских сессий, установите явный TTL для каждого ключа сессии, например, 30 минут. volatile-ttl может работать, когда оставшееся время жизни является наиболее важным сигналом. Если ваше приложение обновляет TTL сессий при активности, активные сессии естественным образом сохраняют более длинный оставшийся TTL. Если оно не обновляет TTL, рассмотрите volatile-lru или volatile-lfu вместо этого.

# 1. Установить maxmemory (например, 10 ГБ)
CONFIG SET maxmemory 10gb

# 2. Выбрать политику, нацеленную на данные с временем жизни
CONFIG SET maxmemory-policy volatile-ttl

Практический пример: Реализация HTTP-кэша

Для кэширования полных HTTP-ответов (которые не всегда могут иметь установленный TTL) вы хотите сохранить данные, к которым обращаются чаще всего, даже если эти данные не трогали несколько часов. allkeys-lru или allkeys-lfu идеально подходят.

# Использовать LFU для сохранения действительно 'горячих' объектов, независимо от времени их создания
CONFIG SET maxmemory-policy allkeys-lfu

Мониторинг и настройка

После выбора политики необходим непрерывный мониторинг. Вы должны отслеживать следующие метрики с помощью команды INFO:

  • used_memory: Насколько вы близки к лимиту maxmemory.
  • evicted_keys: Скорость, с которой Redis удаляет данные. Постоянно высокая скорость вытеснения указывает на то, что ваш параметр maxmemory слишком мал для вашей нагрузки или ваша политика вытеснения слишком агрессивна.
  • Коэффициент попадания в кэш приложения: Конечная мера успеха. Если ваш коэффициент попадания падает при увеличении давления на память, необходимо скорректировать выбор политики или лимит maxmemory.

Лучшая практика: При настройке maxmemory всегда оставляйте запас безопасности (например, 10-20% свободной памяти) для учета буферизации репликации, буферизации команд и потенциальных накладных расходов от внутренних структур данных Redis.

Итоговый вывод

Начните с allkeys-lru для общего кэша, allkeys-lfu, когда небольшой набор горячих ключей доминирует в трафике, и политику volatile-* только тогда, когда ключи без срока истечения должны быть защищены. Затем следите за evicted_keys, коэффициентом попадания в приложение и ошибками записи под нагрузкой, прежде чем считать политику завершенной.