Redis回调式get无输出及缓存性能无提升问题排查
问题解决方案
1. 回调形式调用redisClient.get()无输出
原因
你使用的是node-redis v4+版本,该版本默认采用Promise优先的API设计,不再直接支持传统的回调函数传入方式。直接给get()方法传回调不会触发执行,因此看不到输出。另外,你的Redis客户端初始化是异步完成的,如果请求在客户端连接就绪前到达,回调模式不会自动排队请求,而Promise/await模式会自动排队,这也是await能正常工作的核心原因。
解决办法
方法一:推荐使用Promise/await写法(你已验证可用)
保持你当前的await redisClient.get(username)写法即可,这是node-redis v4+的标准用法。
方法二:强制使用回调模式(不推荐)
如果一定要用回调,需要调用.callback()方法将Promise转为回调风格:
redisClient.get(username).callback((err, data) => { if (err) { console.error(err); return; } console.log(data); });
额外优化:确保Redis连接完成后再处理请求
将Express服务的启动逻辑放在Redis连接成功之后,避免请求在客户端未就绪时到达:
let redisClient; let app = express(); // 假设你已初始化Express实例 (async () => { redisClient = redis.createClient(); redisClient.on("error", (error) => console.error(`Error : ${error}`)); redisClient.on("connect", function () { console.log("Redis Connected!"); }); await redisClient.connect(); // 连接完成后启动服务 app.listen(3000, () => console.log("Server running on port 3000")); })();
2. 缓存命中与未命中响应耗时一致
原因
核心问题是缓存并未真正生效,导致每次请求都走GitHub API流程,因此耗时一致。具体诱因包括:
- 缓存写入时未等待操作完成,且未设置过期时间,可能导致缓存未成功写入;
- 中间件读取缓存后,直接将字符串格式的缓存数据传入
setResponse,如果该函数期望数字类型,可能导致响应异常,但表面看起来和未命中时一致; - Redis客户端未就绪时处理请求,导致缓存写入失败。
解决办法
优化缓存中间件逻辑
去掉冗余的await+.then()嵌套,直接使用await读取缓存,并将字符串缓存转为对应类型:
async function cache(req, res, next) { const { username } = req.params; try { const data = await redisClient.get(username); if (data !== null) { // 将缓存的字符串转为数字(因为存储的是JSON.stringify(repos),repos是数字) res.send(setResponse(username, parseInt(data, 10))); return; } next(); } catch (error) { console.log(error.toString()); next(); // 缓存读取失败时,继续走下游逻辑 } }
确保缓存写入成功并设置过期时间
在getRepos中,等待set操作完成,并添加过期时间(避免缓存永久有效):
// Set data to Redis with 60 seconds expiration await redisClient.set(username, JSON.stringify(repos), { EX: 60 // 可根据需求调整过期时间 });
配合Redis连接就绪后启动服务
按照问题1中的优化方案,确保服务在Redis连接完成后再启动,避免缓存写入失败。
内容的提问来源于stack exchange,提问作者Irakli Ardia
相关产品推荐
相关产品推荐

