关于redis使用set时设置超时时间的问题

本文探讨了Redis中SET命令设置超时时间的问题。当同时使用EX和PX选项时,只有PX的毫秒级别设置生效。示例中显示,尽管尝试设置1.5秒的超时,但实际只应用了毫秒部分。这表明接口文档可能需要更新以反映这一行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   redis的官网(http://redis.io)中是这样描述的:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type. Any previous time to live associated with the key is discarded on successful SEToperation.

Options

Starting with Redis 2.6.12 SET 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.

Note: Since the SET command options can replace SETNXSETEXPSETEX, it is possible that in future versions of Redis these three commands will be deprecated and finally removed.

Return value

Status code replyOK if SET was executed correctly. Null multi-bulk reply: a Null Bulk Reply is returned if the SET operation was not performed becase the user specified the NX or XX option but the condition was not met.

Examples

redis>  SET mykey "Hello"
OK
redis>  GET mykey
"Hello"
redis> 


如果按上面的描述,我们想给一个key设置1.5秒的超时时间,那么一种可能是:SET name zl EX 100 PX 500,这时我们的期望是得到1秒加500毫秒的超时时间,执行结果如下:


127.0.0.1:6380[5]> SET name zl EX 100 PX 500
OK
127.0.0.1:6380[5]> pttl name
(integer) -2
127.0.0.1:6380[5]> pttl name
(integer) -2
127.0.0.1:6380[5]> set name zl ex 100
OK
127.0.0.1:6380[5]> pttl name
(integer) 97949
127.0.0.1:6380[5]> pttl name
(integer) 93010

但实际中,当同时设置了秒和毫秒时,只有毫秒起了作用,也就是说,接口的描述应该改为:

SET key value [EX seconds | PX milliseconds] [NX|XX]

另外,从源中看,的确存在只使用秒或者毫秒的情况:
/* SET key value [NX] [XX] [EX <seconds>] [PX <milliseconds>] */
void setCommand(redisClient *c) {
    int j;
    robj *expire = NULL;
    int unit = UNIT_SECONDS;
    int flags = REDIS_SET_NO_FLAGS;

    for (j = 3; j < c->argc; j++) {
        char *a = c->argv[j]->ptr;
        robj *next = (j == c->argc-1) ? NULL : c->argv[j+1];

        if ((a[0] == 'n' || a[0] == 'N') &&
            (a[1] == 'x' || a[1] == 'X') && a[2] == '\0') {
            flags |= REDIS_SET_NX;
        } else if ((a[0] == 'x' || a[0] == 'X') &&
                   (a[1] == 'x' || a[1] == 'X') && a[2] == '\0') {
            flags |= REDIS_SET_XX;
        } else if ((a[0] == 'e' || a[0] == 'E') &&
                   (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' && next) {
            unit = UNIT_SECONDS;
            expire = next;
            j++;
        } else if ((a[0] == 'p' || a[0] == 'P') &&
                   (a[1] == 'x' || a[1] == 'X') && a[2] == '\0' && next) {
            unit = UNIT_MILLISECONDS;
            expire = next;
            j++;
        } else {
            addReply(c,shared.syntaxerr);
            return;
        }
    }

    c->argv[2] = tryObjectEncoding(c->argv[2]);
    setGenericCommand(c,flags,c->argv[1],c->argv[2],expire,unit,NULL,NULL);
}
请大家在使用时务必要注意!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值