Nodejs中redis的mset可以像set一样设置过期时间吗

Nodejs中redis的mset可以像set一样设置过期时间吗

看了下api,貌似不支持,因为我有一个列表(比如说20个),需要缓存到redis,如果一个一个的去redis.set(‘key’,‘value’,‘NX’,‘EX’,60,cb);效率有点低,就想用redis.mset(‘key’,‘value’,‘key’,‘value’,‘key’,‘value’,…,cb)一次性缓存过去,但是不能设置过期时间了

4 回复

Node.js 中 Redis 的 mset 可以像 set 一样设置过期时间吗?

问题描述

在使用 Node.js 操作 Redis 时,我们可能会遇到这样一个需求:将多个键值对同时存储到 Redis 中,并且希望为每个键值对设置一个过期时间。通过查阅文档,发现 redis.mset 方法似乎并不支持直接设置过期时间。

例如,如果我们有 20 个键值对需要缓存,逐个调用 redis.set('key', 'value', 'NX', 'EX', 60, cb) 会显得效率低下。

解决方案

虽然 mset 方法本身不支持设置过期时间,但我们可以通过一些技巧来实现这一需求。具体来说,我们可以先使用 mset 方法批量设置键值对,然后再使用 mset 方法中的键来批量设置过期时间。

以下是一个具体的示例代码:

const redis = require("redis");
const client = redis.createClient();

// 批量设置键值对
const keysValues = {
    key1: "value1",
    key2: "value2",
    // 更多键值对...
};

const keys = Object.keys(keysValues);
const values = Object.values(keysValues);

client.mset(keys, values, (err, replies) => {
    if (err) throw err;

    console.log("Keys set successfully:", replies);

    // 设置过期时间
    const expireCommands = [];
    for (let i = 0; i < keys.length; i++) {
        expireCommands.push(keys[i]);
        expireCommands.push(60); // 过期时间为 60 秒
    }

    client.mset(expireCommands, (err, replies) => {
        if (err) throw err;

        console.log("Expire times set successfully:", replies);
    });
});

解释

  1. 批量设置键值对

    • 使用 client.mset(keys, values, callback) 方法一次性设置多个键值对。
  2. 设置过期时间

    • 在设置完键值对后,使用 client.mset(expireCommands, callback) 方法为每个键设置过期时间。这里我们通过遍历所有键并构造一个命令数组 expireCommands 来实现这一点。

通过这种方式,我们可以在一次操作中批量设置键值对及其过期时间,从而提高效率。

这种方法虽然稍微复杂一点,但可以满足在 mset 方法中批量设置键值对及其过期时间的需求。


实在不行,弄个计划任务,定期清理一下

如果担心发出多个命令的效率,那大可不必。nodejs的redis客户端默认是使用pipeline通讯策略的,一个命令 ≠ 一次tcp连接,在一个连接上可以发出n个命令。单个命令和多个命令的区别只在于传递数据量的多少,除此之外没有额外的消耗。可以通过网络抓包工具,看看redis客户端与服务器端的通讯数据的响应情况。

在Node.js中使用Redis时,redis.mset方法本身并不直接支持为每个键值对单独设置过期时间。不过,你可以通过其他方式来实现类似的功能。

解决方案

  1. 逐个设置键值对及过期时间:虽然这会降低一些性能,但这是最简单的方法。

    const redis = require("redis");
    const client = redis.createClient();
    
    // 假设你的键值对列表如下
    const keysValues = {
      key1: "value1",
      key2: "value2",
      key3: "value3",
      // 添加更多键值对
    };
    
    // 同时设置多个键值对并设置过期时间
    function setMultipleWithExpiry(keysValues, expirySeconds) {
      for (const [key, value] of Object.entries(keysValues)) {
        client.set(key, value, 'EX', expirySeconds, () => {});
      }
    }
    
    // 使用示例
    setMultipleWithExpiry(keysValues, 60); // 设置所有键值对的过期时间为60秒
    
  2. 批量设置键值对后统一设置过期时间:这种方法需要先用mset批量设置键值对,然后再逐一设置过期时间。这样可以在一次网络调用中完成多个键值对的设置,并在随后的一次网络调用中设置它们的过期时间。

    const redis = require("redis");
    const client = redis.createClient();
    
    // 假设你的键值对列表如下
    const keysValues = {
      key1: "value1",
      key2: "value2",
      key3: "value3",
      // 添加更多键值对
    };
    
    // 批量设置键值对
    function mSetAndExpire(keysValues, expirySeconds) {
      const keys = [];
      const values = [];
    
      for (const [key, value] of Object.entries(keysValues)) {
        keys.push(key);
        values.push(value);
      }
    
      client.mset(keys, values, () => {
        // 在这里设置过期时间
        for (const key of keys) {
          client.expire(key, expirySeconds, (err) => {
            if (err) console.error(err);
          });
        }
      });
    }
    
    // 使用示例
    mSetAndExpire(keysValues, 60); // 设置所有键值对的过期时间为60秒
    

总结

尽管mset方法本身不支持同时设置多个键值对的过期时间,但可以通过上述两种方法之一来实现这一需求。第一种方法更为直接,而第二种方法则更高效地利用了网络调用,但需要更多的逻辑处理。根据你的具体需求选择合适的方法即可。

回到顶部