节点Redis - SET与EX和NX



Redis推荐使用带有可选参数的SET作为锁定机制的方法。也就是说,SET lock 1 EX 10 NX只在它不存在的情况下才会设置一个锁,并且它将在10秒后过期。

我使用节点Redis,它有一个set()方法,但我不确定如何传递它的额外参数有密钥过期,而不是被创建,如果它已经存在,或者即使它是可能的。

也许我必须使用setnx()expire()作为单独的调用?

在阅读Node Redis源代码后,我发现所有方法都接受任意数量的参数。当一个错误关于不正确的参数数量产生,这是由Redis而不是节点模块产生的。

我早期尝试提供多个参数是因为我只有Redis 2.2。在2.6.12版本中,SET只接受NX和EX参数。

所以安装了Redis 2.6.12,下面的方法调用将与节点Redis一起设置一个变量,如果它不存在,并设置它在5分钟后过期:

$client->set('hello', 'world', 'NX', 'EX', 300, function(err, reply) {...});
$client->set(['hello', 'world', 'NX', 'EX', 300], function(err, reply) {...});

您可以使用Lua脚本制作自己的setnex命令。所有的Lua脚本都是自动运行的,所以你不必担心其他客户端会更改你已经在脚本中读取的数据。

-- setnex.lua
local key = ARGV[1]
local expiry = ARGV[2]
local value = ARGV[3]
local reply = redis.call("SETNX", key, value)
if 1 == reply then 
  redis.call("EXPIRE", key, expiry) 
end
return reply

你可以像这样从node_redis调用它:

client.eval(setnex_lua, 0, "mykey", 10, "myvalue", function (err, res) {
    console.dir(err);
    console.dir(res);
});

Node-Redis v4+ changes

值得注意的是,从node-redis v4开始,包发生了重大变化,其中之一是函数默认返回承诺,命令的修饰符可以使用JavaScript对象作为可选参数指定:

await client.set('key', 'value', {
  EX: 300,
  NX: true
});

另外,您可以使用sendCommand:

运行任何您想要的命令:
await client.sendCommand(['SET', 'key', 'value', 'NX', 'EX', 300]);

最新更新