【问题标题】:Problem using ioredis scanStream() to scan through all Redis keys使用 ioredis scanStream() 扫描所有 Redis 键时出现问题
【发布时间】:2020-08-19 15:26:06
【问题描述】:

我正在尝试在 NodeJS 应用程序中将所有 Redis 密钥与 MongoDB 同步。

我使用 ioredis 作为 NodeJS Redis 客户端,并尝试通过使用scanStream() function 来实现上述目的。这个函数被认为是一种使用流扫描光标中所有键的更简单方法。

这是我用来尝试扫描所有键的代码:

const stream = await redis.scanStream();
stream.on("data", async (resultKeys) => {
  await stream.pause();
  for (let i = 0; i < resultKeys.length; i++) {
    try {
      let KEY = resultKeys[i];
      let redisObjectStr = await redis.get(KEY);
      let redisObject = JSON.parse(redisObjectStr);

      // Sync Redis key with MongoDB
      const user = await User.findOne({
        apiKey: KEY
      }).exec();

      if (user) {
        user.color = redisObject.color;
        user.size = redisObject.size;
        await user.save();
        await stream.resume();
      }
    } catch (err) {
      next(err)
    }
  }
});
stream.on("end", () => {
  console.log("all keys have been visited")
  res.send("done")
})

但是我收到以下错误:

api_1 |所有键都已访问 proxy_1 | 172.18.0.1 - - [22/Jan/2019:12:52:06 +0000]“GET /api/syncredis HTTP/1.1”200 4“-” "邮递员运行时/7.6.0" "-" api_1 | ::ffff:172.18.0.6 - - [22/Jan/2019:12:52:06 +0000]“GET /api/syncredis HTTP/1.1”200 4“-” “邮递员运行时/7.6.0” api_1 | SyntaxError: Unexpected token l in JSON 在位置 0 api_1 |在 JSON.parse() api_1 |在 ScanStream.stream.on (/usr/src/app/routes/testRoute.js:428:32) api_1 |在 process.internalTickCallback (internal/process/next_tick.js:77:7) api_1 |错误 [ERR_HTTP_HEADERS_SENT]:之后无法设置标头 它们被发送给客户

【问题讨论】:

  • 您在 redis 中的某些键的数据中似乎没有 JSON 格式。或者另一种情况 - 其中一些不是字符串键,redis.get 将失败。

标签: node.js redis ioredis


【解决方案1】:

我假设您使用的是简单的 redis 而不是集群的。您应该尝试将其包装在一个 Promise 中,以便它直接跳转到 stream.end 并检查您从 redis.get 获得的结果,检查它是否是正确的可解析 json 字符串。

我建议从不同的函数中获取所有键,然后迭代所有键,使其与 mongo 同步。

代码:-

let arrOfKeys = await getKeys(prefix);
//loop through all the keys and sync with mongo 

const getKeys = async (prefix = "") => {
    let finalKeyArray = [], keysArray = [];
    let stream = redis.scanStream({
        match: prefix
    });
    return new Promise((res, rej) => {
        stream.on("data", async (keys = []) => {
            let key;
            for (key of keys) {
                if (!keysArray.includes(key)) {
                    await keysArray.push(key);
                }
            }
        });
        stream.on("end", () => {
            res(keysArray);
        });
    }).then((keysets) => {
        keysets.forEach((keySet) => {
            keySet.forEach((key) => {
                if (!finalKeyArray.includes(key)) {
                    finalKeyArray.push(key);
                }
            })
        })
        return finalKeyArray;
    }).catch((err) => {
        console.error("Error while getting redis keys:", err);
        return [];
    });
}

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 2022-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多