Как ограничить память Redis: maxmemory и политика вытеснения

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

Смотрим текущее потребление

Подключаемся к Redis:

redis-cli

И запрашиваем статистику по памяти:

INFO MEMORY

Важные поля:

  • used_memory: сколько памяти реально занял Redis;
  • used_memory_rss: сколько видит операционная система, может быть больше из-за фрагментации;
  • maxmemory: текущий лимит, 0 значит «без ограничений»;
  • maxmemory_policy: что делать при достижении лимита.

Если maxmemory равен нулю, Redis будет расти, пока не закончится память и система не убьёт процесс через OOM killer. Отдельно лимит можно посмотреть так:

CONFIG GET maxmemory

Значение выводится в байтах.

Как выбрать лимит

Лимит выбирают не по тому, сколько кэша хочется, а по тому, сколько памяти можно отдать Redis без вреда для остальных сервисов. Если на сервере только Redis, можно смелее. Если рядом Nginx, PHP-FPM и база данных, осторожнее. Грубое правило для VPS под WordPress:

  • 2 ГБ памяти: Redis от 128 до 256 МБ;
  • 4 ГБ: от 256 до 512 МБ;
  • 8 ГБ: от 512 МБ до 1 ГБ.

Дальше смотрите по факту. Зачем вообще WordPress нужен Redis, я объяснял в заметке «Ещё немного о Redis».

Временный лимит

Чтобы проверить гипотезу без правки конфигов, лимит можно задать на лету:

CONFIG SET maxmemory 256mb
CONFIG GET maxmemory

Это изменение действует до перезапуска Redis.

Постоянный лимит

Чаще всего конфиг лежит в /etc/redis/redis.conf. Добавляем или меняем строки:

maxmemory 256mb
maxmemory-policy allkeys-lru

Перезапускаем и проверяем:

sudo systemctl restart redis-server
redis-cli CONFIG GET maxmemory
redis-cli INFO MEMORY | grep -E 'used_memory:|maxmemory:|maxmemory_policy:'

Политика вытеснения

Лимит без правильной политики часто бесполезен. По умолчанию стоит noeviction: при переполнении Redis просто начинает отказывать в записи, и сайт может работать хуже, чем совсем без кэша. Основные варианты:

  • noeviction: ничего не удалять, отказывать в записи;
  • allkeys-lru: удалять давно не использованные ключи среди всех;
  • volatile-lru: то же, но только среди ключей со сроком жизни (TTL);
  • allkeys-random: удалять случайные ключи;
  • volatile-ttl: удалять ключи, срок которых истекает раньше.

Для объектного кэша WordPress обычно выбирают allkeys-lru. Если приложение ставит TTL на все ключи, можно взять volatile-lru.

Проверяем, как работает кэш

redis-cli INFO STATS | grep -E 'evicted_keys|keyspace_hits|keyspace_misses'
redis-cli --stat

Если растёт evicted_keys, Redis упирается в лимит и выбрасывает ключи. Само по себе это нормально. Плохо, когда вытеснений много и одновременно растёт keyspace_misses: значит, кэш не успевает приносить пользу, и лимит стоит увеличить.

Рабочий минимум такой: задать maxmemory, выбрать политику вытеснения и через день-два нагрузки посмотреть INFO MEMORY и INFO STATS. Как подключить Redis к WordPress, рассказано в заметке о Redis на HestiaCP.

Источники и ссылки


Комментарии загружаются…