Ответ
Когда Redis достигает лимита памяти (maxmemory), он начинает вытеснять данные согласно заданной политике (maxmemory-policy).
Основные политики вытеснения:
-
noeviction(по умолчанию): Redis не удаляет данные, а возвращает ошибку на команды записи (SET,LPUSHи т.д.). Команды чтения продолжают работать. -
LRU (Least Recently Used) — вытеснение давно неиспользуемых ключей:
allkeys-lru: Удаляет наименее используемый ключ из всех ключей.volatile-lru: Удаляет наименее используемый ключ только среди тех, у которых установленexpire(TTL).
-
LFU (Least Frequently Used) — вытеснение наименее часто используемых ключей:
allkeys-lfu: Удаляет ключ с наименьшим количеством обращений из всех ключей.volatile-lfu: Удаляет ключ с наименьшим количеством обращений среди тех, у которых установленexpire.
-
Другие политики:
allkeys-random: Удаляет случайный ключ из всех.volatile-random: Удаляет случайный ключ из тех, у которых установленexpire.volatile-ttl: Удаляет ключ с наименьшим оставшимся временем жизни (TTL) среди тех, у которых установленexpire.
Дополнительные стратегии управления памятью:
- TTL (Time-To-Live): Проактивно устанавливать срок жизни для ключей, которые не нужно хранить вечно (
EXPIRE,SETEX). - Шардирование (Sharding): Горизонтально масштабировать данные, распределяя их по нескольким инстансам Redis (например, с помощью
Redis Cluster). - Сжатие данных: Хранить значения в сжатом виде (например, используя
MessagePackилиProtobufвместоJSON), что уменьшает потребление памяти. - Оптимизация структур данных: Использовать более эффективные с точки зрения памяти структуры данных Redis, когда это возможно (например,
Hashes,Lists,Sorted Setsвместо хранения больших JSON-объектов в строках).
Настройка политики выполняется в конфигурационном файле или через команду CONFIG SET:
# В файле redis.conf (рекомендуемый способ)
maxmemory 2gb
maxmemory-policy allkeys-lru
# Или в рантайме через redis-cli
CONFIG SET maxmemory "2gb"
CONFIG SET maxmemory-policy allkeys-lru Ответ 18+ 🔞
Ага, слушай, вот сидишь ты такой, настраиваешь свой Redis, всё летает, всё пиздец как быстро. И тут — бац! — память кончилась. И что, думаешь, он тебе вежливо так скажет: «Извините, барин, места нет»? Да хуй там! Он начнёт выкидывать твои данные нахуй, как старые носки, по какому-то своему закону. А закон этот — политика вытеснения, maxmemory-policy. И если её не настроить, будет пиздец.
Ну, и какие у нас варианты, блядь?
-
noeviction(дефолтная, она же «пошли все нахуй, я не убираюсь»). Redis просто перестаёт записывать что-либо новое и орёт тебе в ответ ошибку на каждую команду вродеSET. Читать-то можно, но писать — нет. Как будто квартира забита хламом, и ты уже не можешь новую тапку занести, пока старую не выкинешь. Но выкидывать он не хочет. Самодур, блядь. -
LRU (Least Recently Used) — «Кто давно не трогал — тот и лох».
allkeys-lru: Вышвыривает на мороз ключ, до которого дольше всех не доходили руки, из ВСЕХ ключей. Без разбора.volatile-lru: То же самое, но только среди тех ключей, у которых есть срок годности (expire). То есть, которые ты сам пометил как временные. Остальные трогать не будет.
-
LFU (Least Frequently Used) — «Кто редко звонит — тому и хуй, а не место».
allkeys-lfu: Выгоняет того, к кому реже всего обращались. Считает, блядь, обращения. Популярность-конкурс.volatile-lfu: Аналогично, но только среди ключей с TTL.
-
Прочие художества:
allkeys-random: Просто тыкает пальцем в небо и удаляет случайный ключ. Русская рулетка, ебать.volatile-random: То же самое, но из временных.volatile-ttl: Самый справедливый, на мой взгляд. Смотрит на ключи с установленным сроком и первым делом отправляет в утиль того, у кого этот срок вот-вот кончится. Типа «ты всё равно скоро сдохнешь, давай поможем».
А что ещё можно сделать, чтобы не доводить до ручки?
- TTL (Time-To-Live): Не будь жадиной, ставь ключам срок жизни командой
EXPIRE. Зачем тебе вечно хранить кэш сессии пользователя, который зашёл один раз в 2015 году? Самоуничтожится — и память свободна. - Шардирование: Если один инстанс не справляется — раскидай данные по нескольким.
Redis Clusterтебе в помощь. Это как вместо одной огромной помойки завести несколько аккуратных мусорных баков. - Сжатие данных: Не пихай в него сырые JSON-ы размером с «Войну и мир». Сожми их чем-нибудь, типа
MessagePack. Места в разы меньше займёт, ёпта. - Оптимизация структур: Не храни всё в простых строках (
SET). Если данные структурированные — используйHashes. Они жутко экономят память. Это как вместо того, чтобы каждый носк хранить в отдельной коробке, сложить все носки в один комод.
Ну и главное — как это всё включить. Конфиг файл — твой лучший друг, не ебнись с настройками в рантайме на проде.
# Пишешь в redis.conf и спишь спокойно
maxmemory 2gb
maxmemory-policy allkeys-lru
# Или, если совсем припёрло и надо прямо сейчас, через консоль
CONFIG SET maxmemory "2gb"
CONFIG SET maxmemory-policy allkeys-lru
А то без этого твой Redis превратится в ту самую собаку Муму, которую пришлось топить, потому что места не было. Только топить-то будет он твои же данные, блядь. Думай головой!