如何更新redis值而不影响剩余的TTL?

2w2cym1i  于 2022-12-11  发布在  Redis
关注(0)|答案(7)|浏览(769)

有没有可能SET redis密钥而不删除它们现有的ttl?目前我所知道的唯一方法是找到ttl并做一个SETEX,但这似乎不太准确。

axr492tv

axr492tv1#

KEEPTTL选项将添加到redis〉=6.0中的SET

https://redis.io/commands/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.
tp5buhyn

tp5buhyn2#

根据Redis的documentationSET命令删除TTL,因为密钥被覆盖。
但是,您可以使用EVAL命令来评估Lua脚本,以便自动执行此操作。
下面的脚本检查密钥的TTL值,如果该值为正,则使用新值和剩余的TTL调用SETEX
本地ttl = redis.call('ttl ',ARGV[1])如果ttl〉0,则返回redis.call('SETEX',ARGV[1],ttl,ARGV[2])end
示例:
〉设置键123
好的
〉过期密钥120
(整数)1
...几秒钟后
〉TTL键
(整数)97
如果redis.callttl〉0,则返回redis.call(“SETEX”,ARGV [1],ttl,ARGV[2])end”0键987
好的
〉TTL键
96
〉获取密钥
“九八七”

qoefvg9y

qoefvg9y3#

也许INCRINCRBYDECR等可以帮助你。它们不修改TTL。

> setex test 3600 13
OK

> incr test
(integer) 14

> ttl test
(integer) 3554

http://redis.io/commands/INCR

o7jaxewo

o7jaxewo4#

通过使用SETBIT根据新值逐个更改值位,可以更改值而不影响其密钥上的TTL。
然而,这种方法的缺点是明显的性能影响,特别是当值相当大时。

注意:建议在事务(多执行)块中执行此操作

我们自己维护TTL

  • 正在获取当前TTL
  • 设置新值
  • 设置值后恢复TTL

由于所执行的命令的未知持久性,因此显然是不可取的。
另一种方法是使用List作为数据类型,在用LPUSH向列表添加新值后,使用LTRIM将列表的大小保持为单个元素。这不会改变键上的TTL。

lymgl2op

lymgl2op5#

下面是一个检查现有TTL并在需要时使用它的函数。
expire参数0 -使用现有的过期时间,〉0 -设置新的过期时间,undefined -没有过期时间。

/**
       * 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);
        });
      };
ttisahbt

ttisahbt6#

有一种方法可以从Redis获取剩余的TTL。

Redis中维护TTL
1.获取当前TTL
1.设置新值
1.设置值后恢复TTL

范例:

// This function helps to get the  Remaining TTL from the redis.
        const  getRemainingTTL=(key)=> {  
            return new Promise((resolve,reject)=>{
                redisClient.TTL(key,(err,value)=>{
                    if(err)reject(err);
                    resolve(value);
                });
            });
        };
     let remainingTTL=await getRemainingTTL(otpSetKey);
     console.log('remainingTTL',remainingTTL);

     redisClient.set(key,newValue,'EX',exTime ); // set agin
liwlm1x9

liwlm1x97#

由于某种原因对我来说这种功能没有起作用:

redisSender.set('tenMinWaitTime', avg, 'KEEPTTL')

我需要写的是:

redisSender.set('tenMinWaitTime', avg, { KEEPTTL: true })

文档可在以下位置找到:https://www.npmjs.com/package//redis

相关问题