Раздел 37 · Redis с нуля

TTL, политики вытеснения и maxmemory

junior~20 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

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

Холодильник в общежитии

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

Но бывает и другая беда: холодильник забит, а продукты ещё свежие. Тогда нужно правило, кто вылетает первым. Можно выбросить то, к чему дольше всех не прикасались. Можно то, что берут реже всего. А можно повесить табличку «мест нет» и больше ничего не принимать.

В Redis есть обе части. Сроки годности это TTL из урока про ключи. А правило для переполненного холодильника называется политикой вытеснения.

Как Redis удаляет протухшие ключи

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

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

127.0.0.1:6379> SET temp:x 1 PX 100
OK

Через пару сотен миллисекунд:

127.0.0.1:6379> GET temp:x
(nil)

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

Сколько ключей удалено по сроку, видно в разделе статистики INFO stats:

127.0.0.1:6379> INFO stats
# Stats
...
expired_keys:2
...
evicted_keys:0
...

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

Для приложения важен вывод: протухший ключ никогда не вернётся в ответе. А вот память он может занимать ещё какое-то время, пока до него не дойдёт фоновый цикл.

Потолок памяти: maxmemory

Сколько памяти Redis разрешено занять, задаёт настройка maxmemory. По умолчанию она равна нулю, то есть предела нет:

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

Без предела Redis будет расти, пока не займёт всю память машины, и тогда операционная система может его убить. Для кэша предел ставят всегда. Задать его можно на ходу командой CONFIG SET, единицы понимаются привычные:

127.0.0.1:6379> CONFIG SET maxmemory 100mb
OK
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "104857600"

CONFIG SET меняет настройку только до перезапуска. Чтобы она пережила рестарт, её пишут в файл redis.conf строкой maxmemory 100mb или передают флагом при запуске: redis-server --maxmemory 100mb.

урок из курса

Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.