Redis предоставляет нам функции EXPIRE
и TTL
. Согласно документации, команда TTL
может использоваться для различения несуществующего и просроченный ключ:
> SET foo 3
OK
> GET foo
"3"
> EXPIRE foo 5
(integer) 1
> TTL foo
(integer) 3
> TTL foo
(integer) 2
> TTL foo
(integer) 1
> TTL foo
(integer) 0
> TTL foo
(integer) -2
Согласно спецификации EXPIRE, просроченные объекты фактически удаляются из хранилище либо при доступе к ним, либо через периодический случайный выбор ключей с истекшим сроком действия:
В частности, это то, что Redis делает 10 раз в секунду:
Протестируйте 20 случайных ключей из набора ключей с соответствующим сроком действия.
Удалите все найденные ключи с истекшим сроком действия.
Если срок действия более 25 ключей истек, начните снова с шага 1.
Но как насчет -2
(или информации, позволяющей генерировать ее вместо -1
)? Хранится ли он навсегда или существует политика сбора мусора?
Также обратите внимание, что если мы установим и удалим новое значение для того же ключа, -2
сохранится:
> SET foo 3
OK
> ttl foo
(integer) -1
> del foo
(integer) 1
> ttl foo
(integer) -2
Так, например, предположим, что у нас есть скрипты, которые продолжают устанавливать ключи с инкрементными именами и заставляют их истекать через 1 секунду. Собираемся ли мы исчерпать память через сколь угодно долгое время?