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

   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毫秒的超时时间,执行结果如下:

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

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);
}
请大家在使用时务必要注意!



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

上一篇:Erlang热部署 - 心跳机制(heart)


下一篇:设计模式-结构型模式总结实例(三)