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 SETNX, SETEX, PSETEX, it is possible that in future versions of Redis these three commands will be deprecated and finally removed.
Return value
Status
code reply: OK
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
OKredis> GET mykey
"Hello"
如果按上面的描述,我们想给一个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);
}
请大家在使用时务必要注意!