javascript - How to get the TTL of multiple Redis keys from Node - Stack Overflow

I'm trying to show a view of all keys that look like 'myprefix:*' and their TTL.I can t

I'm trying to show a view of all keys that look like 'myprefix:*' and their TTL. I can then allow an admin to either expire a key, or 'touch it' (i.e. add an hour to the expiration).

I can use redisClient.keys('myprefix:*', (err, keys) => {}) to get my keys, but the redisClient.ttl mand only accepts a single key, not an array. I don't want to iterate over the array and send n ttl mands.

I know I can probably use multi to send a transaction of ttl mands, but I'm wondering if there's a better way (in JavaScript - not shell) to get all the keys and their TTL in one/two mands?

I'm trying to show a view of all keys that look like 'myprefix:*' and their TTL. I can then allow an admin to either expire a key, or 'touch it' (i.e. add an hour to the expiration).

I can use redisClient.keys('myprefix:*', (err, keys) => {}) to get my keys, but the redisClient.ttl mand only accepts a single key, not an array. I don't want to iterate over the array and send n ttl mands.

I know I can probably use multi to send a transaction of ttl mands, but I'm wondering if there's a better way (in JavaScript - not shell) to get all the keys and their TTL in one/two mands?

Share Improve this question edited Oct 13, 2016 at 19:59 Traveling Tech Guy asked Oct 13, 2016 at 18:55 Traveling Tech GuyTraveling Tech Guy 27.9k25 gold badges116 silver badges166 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

As Redis embedds a Lua interpreter, a solution would be to create a Redis Lua script like this one:

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

Using ioredis, you can simplify the declaration of Redis Lua scripts in NodeJS:

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

// This will define a mand 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 mand, giving the prefix as a parameter
redis.getTtls('myprefix', function (err, result) {
    console.log(result);
});

The script is defined in your NodeJS application, but executed by Redis.

Don't forget that using the KEYS mand in production is often a bad idea, as it scans the whole database in one operation and so makes your Redis instance unresponsive to other requests during a time which could be rather long (it depends on the number of keys in your database). If it's an issue in your use case, you'll probably want to use a SCAN mand instead.

Finally resorted to using multi. I do understand both using keys and multi is highly not remended in production. But the number of keys I'm handling right now is quite small (less than 10).

Using keys + multi to get the ttl of N keys results in 2 network trips, rather than N+1.

As it grows, I'll reevaluate the solution. I posted my code below if anyone ever needs it:

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);
            }
          });
        }
      });
    });
  };

This yields an array:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745064313a4609161.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信