Redis没有缓存,而是每次都去MongoDB



我正在努力让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 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

然而,当我查看我的NewRelic面板时,我发现响应时间非常慢(至少10000毫秒(,这一切都来自MongoDB。Redis只占用大约15-16ms,其他10000ms是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时对其进行解析,所以它应该是这样的:

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中。

最新更新