В прошлом уроке мы решали, когда писать в кэш и когда в базу. Но кэш живёт в оперативной памяти, а она конечна. Магазин кэширует карточки книг, сессии, корзины, и рано или поздно память кончится. Сегодня разбираемся, что 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 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.