我正在尝试在NodeJS应用程序中将所有Redis密钥与MongoDB同步。
我使用ioredis作为NodeJS Redis客户端,并试图通过使用scanStream()函数来实现上述功能。这个函数被认为是通过使用流来扫描光标中所有键的一种更简单的方法。
这是我用来扫描所有钥匙的代码:
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/20199:12:52:06+0000]"GET/api/syncredis HTTP/1.1"200 4"-"PostmanRuntime/7.6.0"-"api_1|:ffff:172.18.0.6--[22/20199:12:52:06+0000]"GET/api/syncredis HTTP/1.1"200 4"-"PostmanRuntime/7.6.0"api_1|SyntaxError:中的意外标记lJSON位于位置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,而不是集群的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 [];
});
}