如何从节点

时间:2016-10-13 18:55:46

标签: javascript node.js redis

我正在尝试显示所有看起来像'myprefix:*'的键及其TTL。 然后,我可以允许管理员使密钥过期,或者“触摸它”(即在到期时加一小时)。

我可以使用redisClient.keys('myprefix:*', (err, keys) => {})来获取密钥,但redisClient.ttl命令只接受单个密钥,而不是数组。我不想迭代数组并发送n ttl个命令。

我知道我可以使用multi发送ttl命令的事务,但我想知道是否有更好的方法(在JavaScript中 - 不是shell )用一两个命令获取所有密钥及其TTL?

2 个答案:

答案 0 :(得分:1)

当Redis嵌入Lua interpreter时,解决方案就是创建一个像这样的Redis Lua脚本:

local keys = redis.call('keys','myprefix:*')
local result = {}
for i,k in ipairs(keys) do 
    local ttl = redis.call('ttl', k)
    result[i] = {ttl}
end
return result

使用ioredis,您可以简化NodeJS中Redis Lua脚本的声明:

var Redis = require('ioredis');
var redis = new Redis();

// This will define a command getTtls:
redis.defineCommand('getTtls', {
  numberOfKeys: 1,
  lua: "local keys = redis.call('keys', KEYS[1]..':*')\n local result = {}\n for i,k in ipairs(keys) do \n local ttl = redis.call('ttl', k)\n result[i] = {ttl}\n end\n return result"
});

// now invoke this new command, giving the prefix as a parameter
redis.getTtls('myprefix', function (err, result) {
    console.log(result);
});

脚本在NodeJS应用程序中定义,但由Redis执行。

不要忘记在生产中使用KEYS命令通常是一个坏主意,因为它在一次操作中扫描整个数据库,因此使得Redis实例在可能相当长的时间内对其他请求没有响应(取决于关于数据库中的键数)。如果在您的用例中存在问题,您可能希望改为使用SCAN命令。

答案 1 :(得分:1)

最后使用multi。我确实理解使用keysmulti都非常不推荐用于制作。但我现在正在处理的密钥数量非常少(少于10个)。

使用keys + multi获取N个密钥的ttl会导致2次网络旅行,而不是N + 1.

随着它的发展,我会重新评估解决方案。如果有人需要,我在下面发布了我的代码:

let getKeys = prefix => {
    return new Promise((resolve, reject) => {
      redisClient.keys(`${prefix}:*`), (err, keys) => {
        if(err) {
          reject(err)
        }
        else {
          let multi = redisClient.multi();
          keys.forEach(k => multi.ttl(k));
          multi.exec((err2, ttls) => {
            if(err2) {
              reject(err2);
            }
            else {
              let result = keys.map((k, i) => ({key: k.replace(`${prefix}:`, ''), ttl: ttls[i]}));
              resolve(result);
            }
          });
        }
      });
    });
  };

这会产生一个数组:

[ { key: '05460a69f7c0d313b7edfcca4f267cee', ttl: 3034 },
  { key: 'b1065bfa82408a10e2d2d0a50df1eef9', ttl: 3031 },
  { key: 'c3aeced2ef08f1c728f0b367c50a962a', ttl: 3019 } ]