Для ключей со сроком действия, установленным в Redis, вам необходимо знать следующее.

Redis

В прошлой статье мы говорили о стратегии ликвидации памяти Redis (портал), на этот раз позвольте мне взглянуть на политику истечения срока действия Redis.

Учащиеся, знакомые с Redis, должны знать, что для каждого ключа Redis можно задать срок действия, по истечении которого ключ будет автоматически удален.

Вопросы, требующие внимания при установке срока действия ключа

1,DEL/SET/GETSETОжидание команды очистит время истечения срока действия

в настоящее время используетДЕЛ, УСТАНОВИТЬ, ПОЛУЧИТЬКогда команда, переопределяющая значение, соответствующее ключу, оперирует ключом с установленным временем истечения срока действия, время истечения срока действия соответствующего ключа будет очищено.

//设置mykey的过期时间为300s
127.0.0.1:6379> set mykey hello ex 300
OK
//查看过期时间
127.0.0.1:6379> ttl mykey
(integer) 294
//使用set命令覆盖mykey的内容
127.0.0.1:6379> set mykey olleh
OK
//过期时间被清除
127.0.0.1:6379> ttl mykey
(integer) -1

2,INCR/LPUSH/HSETОжидание команды не очистит время истечения срока действия

при использованииINCR/LPUSH/HSETЭта команда, которая только изменяет значение ключа, а не перезаписывает все значение, не очистит время истечения срока действия ключа. ИНКР:

//设置incr_key的过期时间为300s
127.0.0.1:6379> set incr_key 1 ex 300
OK
127.0.0.1:6379> ttl incr_key
(integer) 291
//进行自增操作
127.0.0.1:6379> incr incr_key
(integer) 2
127.0.0.1:6379> get incr_key
"2"
//查询过期时间,发现过期时间没有被清除
127.0.0.1:6379> ttl incr_key
(integer) 277

ЛПУШ:

//新增一个list类型的key,并添加一个为1的值
127.0.0.1:6379> LPUSH list 1
(integer) 1
//为list设置300s的过期时间
127.0.0.1:6379> expire list 300
(integer) 1
//查看过期时间
127.0.0.1:6379> ttl list
(integer) 292
//往list里面添加值2
127.0.0.1:6379> lpush list 2
(integer) 2
//查看list的所有值
127.0.0.1:6379> lrange list 0 1
1) "2"
2) "1"
//能看到往list里面添加值并没有使过期时间清除
127.0.0.1:6379> ttl list
(integer) 252

3.PERSISTкоманда очищает время истечения срока действия

когда используешьPERSISTКогда команда преобразует ключ со сроком действия в постоянный ключ, она также очищает срок действия.

127.0.0.1:6379> set persist_key haha ex 300
OK
127.0.0.1:6379> ttl persist_key
(integer) 296
//将key变为持久化的
127.0.0.1:6379> persist persist_key
(integer) 1
//过期时间被清除
127.0.0.1:6379> ttl persist_key
(integer) -1

4. ИспользуйтеRENAMEкоманда, время истечения срока действия старого ключа будет перенесено на новый ключ

Используя, например:RENAME KEY_A KEY_BКоманда переименовывает KEY_A в KEY_B.Независимо от того, установлен ли срок действия KEY_B, новый ключ KEY_B унаследует все характеристики KEY_A.

//设置key_a的过期时间为300s
127.0.0.1:6379> set key_a value_a ex 300
OK
//设置key_b的过期时间为600s
127.0.0.1:6379> set key_b value_b ex 600
OK
127.0.0.1:6379> ttl key_a
(integer) 279
127.0.0.1:6379> ttl key_b
(integer) 591
//将key_a重命名为key_b
127.0.0.1:6379> rename key_a key_b
OK
//新的key_b继承了key_a的过期时间
127.0.0.1:6379> ttl key_b
(integer) 248

Место здесь ограничено, поэтому я не буду перечислять случаи переименования key_a в key_b один за другим, вы можете попробовать на своем компьютере, что key_a установил время истечения, а key_b не установил время истечения.

5. ИспользуйтеEXPIRE/PEXPIREУстановите время истечения срока действия на отрицательное число или используйтеEXPIREAT/PEXPIREATУстановка метки времени истечения срока действия на прошедшее время приведет к удалению ключа.

ИСТЕЧЕНИЕ:

127.0.0.1:6379> set key_1 value_1
OK
127.0.0.1:6379> get key_1
"value_1"
//设置过期时间为-1
127.0.0.1:6379> expire key_1 -1
(integer) 1
//发现key被删除
127.0.0.1:6379> get key_1
(nil)

Истечение срока действия:

127.0.0.1:6379> set key_2 value_2
OK
127.0.0.1:6379> get key_2
"value_2"
//设置的时间戳为过去的时间
127.0.0.1:6379> expireat key_2 10000
(integer) 1
//key被删除
127.0.0.1:6379> get key_2
(nil)

6.EXPIREкоманда для обновления срока действия

Используйте команду expire для ключа с установленным сроком действия, чтобы обновить его срок действия.

//设置key_1的过期时间为100s
127.0.0.1:6379> set key_1 value_1 ex 100
OK
127.0.0.1:6379> ttl key_1
(integer) 95
//更新key_1的过期时间为300s
127.0.0.1:6379> expire key_1 300
(integer) 1
127.0.0.1:6379> ttl key_1
(integer) 295

В версиях ниже Redis 2.1.3 использование команды expire для обновления времени истечения срока действия ключа, для которого установлено время истечения срока действия, завершится ошибкой. А использование LPUSH/HSET и других команд для изменения значения ключа с установленным сроком действия приведет к тому, что Redis удалит ключ.

Политика истечения срока действия Redis

Задумывались ли вы когда-нибудь над вопросом, если в Redis большое количество ключей, как мы можем эффективно узнать ключи с истекшим сроком действия и удалить их, обходя каждый ключ? Если за один и тот же период имеется много ключей с истекшим сроком действия, Redis продолжит обработку событий с истекшим сроком действия и приведет к зависанию инструкций чтения и записи.

Позвольте мне объяснить здесь, что Redis является однопоточным, поэтому некоторые трудоемкие операции могут привести к зависанию Redis.Например, когда объем данных Redis особенно велик, используйте команду keys * для вывода списка всех ключей.

На самом деле Redis используетЛенивое удаление + обычное удалениеКомбинация способов обработки ключей с истекшим сроком действия.

ленивое удаление

так называемыйленивое удалениеТо есть, когда клиент обращается к ключу, Redis проверит время истечения срока действия ключа и немедленно удалит его, если срок его действия истечет.

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

регулярно удалять

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

Redis по умолчанию использует 10 сканирований истечения срока действия в секунду:

  1. Случайные 20 ключей из просроченного словаря

  2. Удалить те 20 ключей, срок действия которых истек

  3. Если истек срок действия более 25% ключей, повторите первый шаг.

В то же время, чтобы гарантировать отсутствие чрезмерного цикла, Redis также устанавливает верхний предел времени сканирования, который по умолчанию не будет превышать 25 мс.

использованная литература

Redis.IO/команды/тошнота…