Node.js Redis没有缓存,而是每次都转到MongoDB
我正在尝试让Redis启动并运行,我让服务器正常工作。然而,当我运行负载测试时,我看到每个查询仍然会转到我的mongoDB,而不是首先查看Redis。我的Redis服务器终端是:Node.js Redis没有缓存,而是每次都转到MongoDB,node.js,mongodb,mongoose,redis,Node.js,Mongodb,Mongoose,Redis,我正在尝试让Redis启动并运行,我让服务器正常工作。然而,当我运行负载测试时,我看到每个查询仍然会转到我的mongoDB,而不是首先查看Redis。我的Redis服务器终端是: 41136:M 22 Sep 2020 14:00:00.641 * Background saving terminated with success 41136:M 22 Sep 2020 14:01:01.074 * 10000 changes in 60 seconds. Saving... 41136:M 2
41136:M 22 Sep 2020 14:00:00.641 * Background saving terminated with success
41136:M 22 Sep 2020 14:01:01.074 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:01:01.076 * Background saving started by pid 42406
42406:C 22 Sep 2020 14:01:05.256 * DB saved on disk
41136:M 22 Sep 2020 14:01:05.305 * Background saving terminated with success
41136:M 22 Sep 2020 14:02:06.043 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:02:06.052 * Background saving started by pid 42439
42439:C 22 Sep 2020 14:02:10.719 * DB saved on disk
41136:M 22 Sep 2020 14:02:10.784 * Background saving terminated with success
41136:M 22 Sep 2020 14:03:11.030 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:03:11.033 * Background saving started by pid 42480
42480:C 22 Sep 2020 14:03:17.592 * DB saved on disk
41136:M 22 Sep 2020 14:03:17.690 * Background saving terminated with success
然而,当我查看New Relic仪表板时,我发现响应时间非常慢(至少10000毫秒),这都是来自MongoDB的。Redis仅占用约15-16ms,其余10000 ms为MongoDB
但是,我的MongoDB索引正确,因为那里的查询只需要1毫秒。我还在database.js文件中使用了.lean()方法
我在用火炮进行负载测试
以下是我的服务器的index.js文件供参考:
require('newrelic');
const express = require('express');
const bodyParser = require('body-parser');
const Images = require('../database-mongo/index.js');
const cors = require('cors');
const redis = require('redis');
const client = redis.createClient();
const RedisServer = require('redis-server');
const server = new RedisServer(6379);
const PORT = 3003;
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/../react-client/dist'));
server.open((err) => {
if (err === null) {
console.log('redis server working')
}
})
let redisMiddleware = (req, res, next) => {
let key = "__expIress__" + req.originalUrl || req.url;
client.get(key, function (err, reply) {
if (reply) {
res.send(reply);
} else {
res.sendResponse = res.send;
res.send = (body) => {
client.set(key, JSON.stringify(body));
res.sendResponse(body);
}
next();
}
});
};
app.get('/images/urls/:itemId', redisMiddleware, (req, res) => {
Images.fetchItemImages(Number(req.params.itemId))
.then((data) => {
if (data) {
res.status(200).send({ data });
} else {
res.sendStatus(404);
}
})
.catch((err) => {
console.log('error with app.get: ', err);
res.status(500).send(err);
})
})
app.listen(PORT, () => {
console.log(`listening on port ${PORT}`);
});
module.exports = app
以下是我的数据库的index.js文件:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/images', { useNewUrlParser: true, useUnifiedTopology: true });
var db = mongoose.connection;
db.on('error', function (err) {
console.log('mongoose connection error: ', err);
});
db.once('open', function () {
console.log('mongoose connected successfully');
});
const imageSchema = new mongoose.Schema({
itemId: Number,
pic1Small: String,
pic1Med: String,
pic1Large: String,
pic2Small: String,
pic2Med: String,
pic2Large: String
});
const Image = mongoose.model('url', imageSchema);
function fetchItemImages(itemId) {
// console.log('fetchImages invoked')
return Image.find({ 'itemId': Number(itemId) }).lean()
}
module.exports = Image;
module.exports.fetchItemImages = fetchItemImages;
我找到了解决办法。缺少两部分。首先,Redis中间件需要有一行代码,在返回JSON时解析JSON,因此它应该如下所示:
let redisMiddleware = (req, res, next) => {
let key = "__expIress__" + req.originalUrl || req.url;
client.get(key, function (err, reply) {
if (reply) {
res.send(JSON.parse(reply));
} else {
res.sendResponse = res.send;
res.send = (body) => {
client.set(key, JSON.stringify(body));
res.sendResponse(body);
}
next();
}
});
};
其次,GET请求需要有.set方法,假设Redis数据库中有数据
app.get('/images/urls/:itemId', redisMiddleware, (req, res) => {
db.fetchItemImages(req.params.itemId)
.then((data) => {
if (data) {
client.set(req.params.itemId, JSON.stringify({ data }))
res.status(200).send({ data });
} else {
res.sendStatus(404);
}
})
.catch((err) => {
console.log('error with app.get: ', err);
res.status(500).send(err);
})
})
发生的事情是,没有任何东西被保存到Redis,因此,当Redis在火炮测试中的每一次测试中都被检查时,没有任何东西被输入Redis