2014-02-20 9 views

ответ

11

Согласно Redis documentation, команда SET удаляет TTL, поскольку ключ перезаписывается.

Однако вы можете использовать команду EVAL, чтобы оценить сценарий Lua, чтобы сделать это автоматически для вас.

В приведенном ниже скрипте проверяется значение TTL ключа, если значение положительное, оно вызывает SETEX с новым значением и с использованием оставшегося TTL.

локальная ТТЛ = redis.call ('ТТЛ', ARGV [1]), если ТТЛ> 0, то возвращают redis.call ('SETEX', ARGV [1], TTL, ARGV [2]) конец

Пример:

> установить ключ 123

OK

> истекают ключ 120

(целое число) 1

... через несколько секунд

> ТТЛ ключ

(целое число) 97

> Eval «локальная ТТЛ = redis.call (» ttl ', ARGV [1]), если ttl> 0, то верните redis.call (' SETEX ', ARGV [1], ttl, ARGV [2]) end "0 ключ 987

OK

> ТТЛ ключ

> получить ключ

"987"

5

Может быть INCR, INCRBY, DECR и т.д. могут помочь вам. Они не изменяют TTL.

> setex test 3600 13 
OK 

> incr test 
(integer) 14 

> ttl test 
(integer) 3554 

http://redis.io/commands/INCR

0

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

expire arguments 0 - использовать существующее время истечения срока действия,> 0 - установить новое время истечения срока действия, неопределенное - без истечения срока.

/** 
     * update an item. preserve ttl or set a new one 
     * @param {object} handle the redis handle 
     * @param {string} key the key 
     * @param {*} content the content - if an object it'll get stringified 
     * @param {number||null} expire if a number > 0 its an expire time, 0 
means keep existing ttl, undefined means no expiry 
     * @return {Promise} 
     */ 
     ns.updateItem = function (handle , key , content,expire) { 

     // first we have to get the expiry time if needed 
     return (expire === 0 ? handle.ttl(key) : Promise.resolve (expire)) 
     .then (function (e) { 

      // deal with errors retrieving the ttl (-1 no expiry, -2 no existing record) 
      var ttl = e > 0 ? e : undefined; 

      // stingify the data if needed 
      var data = typeof content === "object" ? JSON.stringify(content) : content; 

      // set and apply ttl if needed 
      return ttl ? handle.set (key, data , "EX", ttl) : handle.set (key,data); 
     }); 
     }; 
0

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

Недостаток этого подхода, однако, очевидно, влияет на производительность, особенно если значение довольно велико.

ПРИМЕЧАНИЕ: Желательно, чтобы выполнить это в транзакции (мульти EXEC) блокировать

Поддержание TTL сами по

  • Определение текущего TTL
  • Установить новое значение
  • Восстановление TTL после заданного значения

    , очевидно, не объявление видимые из-за неизвестной долговечности выполняемых команд.

Другой альтернативой является использование List как тип данных, и после добавления нового значения в список с использованием LPUSHLTRIM поддерживать размер списка в один элемент. Это не изменит TTL на ключ.