是否可以SET
redis键而不删除现有的ttl?我目前唯一知道的方法是找出ttl并做一个SETEX
,但这似乎不太准确。
答案 0 :(得分:11)
根据Redis documentation,SET
命令会删除TTL,因为密钥会被覆盖。
但是,您可以使用EVAL
命令评估Lua脚本,以便自动为您执行此操作。
下面的脚本检查密钥的TTL值,如果值为正,则使用新值并使用剩余的TTL调用SETEX
。
local ttl = redis.call('ttl',ARGV [1])if ttl> 0然后返回redis.call('SETEX',ARGV [1],ttl,ARGV [2])结束
示例:
>设置键123
行
>到期密钥120
(整数)1
......几秒钟后
> ttl key
(整数)97
> eval“local ttl = redis.call('ttl',ARGV [1])if ttl> 0然后返回redis.call('SETEX',ARGV [1],ttl,ARGV [2])结束”0键987
行
> ttl key
96
>得到钥匙
“987”
答案 1 :(得分:10)
KEEPTTL 选项将在redis> = 6.0中添加到 SET
https://github.com/antirez/redis/pull/6679
The SET command supports a set of options that modify its behavior:
EX seconds -- Set the specified expire time, in seconds.
PX milliseconds -- Set the specified expire time, in milliseconds.
NX -- Only set the key if it does not already exist.
XX -- Only set the key if it already exist.
(!) KEEPTTL -- Retain the time to live associated with the key.
答案 2 :(得分:6)
也许INCR
,INCRBY
,DECR
等可以为您提供帮助。他们没有修改TTL。
> setex test 3600 13
OK
> incr test
(integer) 14
> ttl test
(integer) 3554
答案 3 :(得分:1)
可以通过使用SETBIT根据新值逐个更改值位来更改值而不影响其上的TTL。
然而,这种方法的缺点显然是性能影响,特别是如果价值非常大的话。
注意:建议在事务(多个exec)块中执行此操作
自己维护TTL
设置值
后恢复TTL 由于执行的命令的持久性未知,显然是不可取的。
另一种方法是使用List作为数据类型,并在使用LPUSH将新值添加到列表后使用LTRIM将list的大小保持为单个元素。这不会改变钥匙上的TTL。
答案 4 :(得分:0)
这是检查现有TTL并在需要时使用它的功能。
过期参数 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);
});
};