Redis 不会从缓存中检索数据
Redis won't retrieve data from cache
我正在学习教程并创建了一个 cache.js 文件,该文件接受 mongoose 查询并将其 JSON.stringifies 放入该查询 return 编辑的值的键中。目标是缓存它,然后将 .cache()
附加到 app.js 中,其中 mongoose.find()
是
当前,如果缓存为空,我让它从数据库执行 GET,然后将其存储在缓存中。我有一个
console.log("CACHE VALUE #2");
console.log(cacheValue1);
确保数据被存储并成功输出数据。这条线有效。但是有了这条线,
console.log("CACHE VALUE #1");
console.log(cacheValue);
cacheValue
为空。
这是为什么?
它存储在底部的值和键永远不会改变所以我不明白为什么它不会 return 数据而不是 null。
因此 Cache Value #1
始终为 null,并且 Cache Value #2
具有正确的数据。
控制台输出:
GRABBING FROM DB
CLIENT CONNECTION STATUS: true
Setting CACHE to True
ABOUT TO RUN A QUERY
{"$and":[{"auctionType":{"$eq":"publicAuction"}},{"auctionEndDateTime":{"$gte":1582903244869}},{"blacklistGroup":{"$ne":"5e52cca7180a7605ac94648f"}},{"startTime":{"$lte":1582903244869}}],"collection":"listings"}
CACHE VALUE #1
null
CACHE VALUE #2
(THIS IS WHERE ALL MY DATA SHOWS UP)
const mongoose = require('mongoose');
const redis = require('redis');
const util = require('util');
var env = require("dotenv").config({ path: './.env' });
const client = redis.createClient(6380, process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net', {
auth_pass: process.env.REDISCACHEKEY,
tls: { servername: process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net' }
});
client.get = util.promisify(client.get);
const exec = mongoose.Query.prototype.exec;
mongoose.Query.prototype.cache = function () {
this.useCache = true;
console.log("Setting CACHE to True")
return this;
}
mongoose.Query
.prototype.exec = async function () {
if (!this.useCache) {
console.log("GRABBING FROM DB")
console.log("CLIENT CONNECTION STATUS: " + client.connected);
return exec.apply(this, arguments);
}
console.log("ABOUT TO RUN A QUERY")
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name
}));
//See if we have a value for 'key' in redis
console.log(key);
const cacheValue = await client.get(key);
console.log("CACHE VALUE #1");
console.log(cacheValue);
//If we do, return that
if (cacheValue) {
console.log("cacheValue IS TRUE");
const doc = JSON.parse(cacheValue);
return Array.isArray(doc)
? doc.map(d => new this.model(d))
: new this.model(doc);
}
//Otherwise, issue the query and store the result in redis
const result = await exec.apply(this, arguments);
let redisData = JSON.stringify(result);
//stores the mongoose query result in redis
await client.set(key, JSON.stringify(redisData)), function (err) {
console.error(err);
}
const cacheValue1 = await client.get(key);
console.log("CACHE VALUE #2");
console.log(cacheValue1);
return result;
}
根据您链接的 pastebin,您的查询使用 Date.now()
作为其值。这意味着每次查询 运行 时,时间戳都有不同的值。
因为您的键是实际查询,并且查询具有基于 Date.now()
的动态值,您的键永远不会相同,这就是为什么您以后无法在缓存中找到它们的原因,每个由于 Date.now()
.
的动态值,查询正在生成唯一键
我在一个最小的例子中复制了你的代码,当你 wanted.It 在第一个请求后提供来自 redis 缓存的响应时,我让它工作了。我刚刚记录了值并在您的代码中发现了一些小错误,您很容易发现它们(使用文档调用 this.model,修复设置并删除 redis 客户端的最后一个获取)。我不认为这是缓存响应的最佳方式,因为您在每个请求中都将变量设置为 true,并且在使用 cache.With a 之前到达 mongo 和 mongoose中间件所有这些都是可以避免的,你会带走更多的毫秒,但它仍然不是最糟糕的方式所以这是我的最小工作示例。
const http = require('http')
const mongoose = require('mongoose')
const redis = require('redis')
const port = 3000;
const util = require('util');
const client = redis.createClient()
client.get = util.promisify(client.get);
mongoose.connect('mongodb://localhost:27017/testdb', {useNewUrlParser: true});
const exec = mongoose.Query.prototype.exec;
var Schema = mongoose.Schema;
var testSchema = new Schema({
testfield: String, // String is shorthand for {type: String}
});
var Test = mongoose.model('Test', testSchema);
mongoose.Query.prototype.cache = function() {
this.useCache = true;
console.log("Setting CACHE to True")
return this;
}
mongoose.Query
.prototype.exec = async function () {
if (!this.useCache) {
console.log("GRABBING FROM DB")
console.log("CLIENT CONNECTION STATUS: " + client.connected);
return exec.apply(this, arguments);
}
console.log("ABOUT TO RUN A QUERY")
console.log("Query ==", this.getQuery())
console.log("Collection == ", this.mongooseCollection.name);
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name
}));
//See if we have a value for 'key' in redis
console.log("KEY FROM QUERY AND COLLECTION",key);
const cacheValue = await client.get(key);
console.log("CACHE VALUE #1");
console.log(cacheValue);
//If we do, return that
if (cacheValue) {
console.log("cacheValue IS TRUE");
const doc = JSON.parse(cacheValue);
console.log("DOC == ",doc);
return Array.isArray(doc)
? doc.map(d => d)
: doc
// return exec( Array.isArray(doc)
// ? doc.map(d => new this.model(d))
//: new this.model(doc))
}
//Otherwise, issue the query and store the result in redis
const result = await exec.apply(this, arguments);
// console.log("EXEC === ", exec);
// console.log("result from query == ", result);
let redisData = JSON.stringify(result);
//stores the mongoose query result in redis
console.log("REDis data ===", redisData);
await client.set(key, redisData, function (err) {
console.error(err);
})
return result;
}
const server = http.createServer(function(req, res) {
if(req.url === '/'){
Test.find({}).cache().exec().then(function( docs) {
console.log("DOCS in response == ", docs);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(JSON.stringify(docs))
})
}
})
server.listen(port, function() {
console.log(`Server listening on port ${port}`)
})
我正在学习教程并创建了一个 cache.js 文件,该文件接受 mongoose 查询并将其 JSON.stringifies 放入该查询 return 编辑的值的键中。目标是缓存它,然后将 .cache()
附加到 app.js 中,其中 mongoose.find()
是
当前,如果缓存为空,我让它从数据库执行 GET,然后将其存储在缓存中。我有一个
console.log("CACHE VALUE #2");
console.log(cacheValue1);
确保数据被存储并成功输出数据。这条线有效。但是有了这条线,
console.log("CACHE VALUE #1");
console.log(cacheValue);
cacheValue
为空。
这是为什么?
它存储在底部的值和键永远不会改变所以我不明白为什么它不会 return 数据而不是 null。
因此 Cache Value #1
始终为 null,并且 Cache Value #2
具有正确的数据。
控制台输出:
GRABBING FROM DB
CLIENT CONNECTION STATUS: true
Setting CACHE to True
ABOUT TO RUN A QUERY
{"$and":[{"auctionType":{"$eq":"publicAuction"}},{"auctionEndDateTime":{"$gte":1582903244869}},{"blacklistGroup":{"$ne":"5e52cca7180a7605ac94648f"}},{"startTime":{"$lte":1582903244869}}],"collection":"listings"}
CACHE VALUE #1
null
CACHE VALUE #2
(THIS IS WHERE ALL MY DATA SHOWS UP)
const mongoose = require('mongoose');
const redis = require('redis');
const util = require('util');
var env = require("dotenv").config({ path: './.env' });
const client = redis.createClient(6380, process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net', {
auth_pass: process.env.REDISCACHEKEY,
tls: { servername: process.env.REDISCACHEHOSTNAME + '.redis.cache.windows.net' }
});
client.get = util.promisify(client.get);
const exec = mongoose.Query.prototype.exec;
mongoose.Query.prototype.cache = function () {
this.useCache = true;
console.log("Setting CACHE to True")
return this;
}
mongoose.Query
.prototype.exec = async function () {
if (!this.useCache) {
console.log("GRABBING FROM DB")
console.log("CLIENT CONNECTION STATUS: " + client.connected);
return exec.apply(this, arguments);
}
console.log("ABOUT TO RUN A QUERY")
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name
}));
//See if we have a value for 'key' in redis
console.log(key);
const cacheValue = await client.get(key);
console.log("CACHE VALUE #1");
console.log(cacheValue);
//If we do, return that
if (cacheValue) {
console.log("cacheValue IS TRUE");
const doc = JSON.parse(cacheValue);
return Array.isArray(doc)
? doc.map(d => new this.model(d))
: new this.model(doc);
}
//Otherwise, issue the query and store the result in redis
const result = await exec.apply(this, arguments);
let redisData = JSON.stringify(result);
//stores the mongoose query result in redis
await client.set(key, JSON.stringify(redisData)), function (err) {
console.error(err);
}
const cacheValue1 = await client.get(key);
console.log("CACHE VALUE #2");
console.log(cacheValue1);
return result;
}
根据您链接的 pastebin,您的查询使用 Date.now()
作为其值。这意味着每次查询 运行 时,时间戳都有不同的值。
因为您的键是实际查询,并且查询具有基于 Date.now()
的动态值,您的键永远不会相同,这就是为什么您以后无法在缓存中找到它们的原因,每个由于 Date.now()
.
我在一个最小的例子中复制了你的代码,当你 wanted.It 在第一个请求后提供来自 redis 缓存的响应时,我让它工作了。我刚刚记录了值并在您的代码中发现了一些小错误,您很容易发现它们(使用文档调用 this.model,修复设置并删除 redis 客户端的最后一个获取)。我不认为这是缓存响应的最佳方式,因为您在每个请求中都将变量设置为 true,并且在使用 cache.With a 之前到达 mongo 和 mongoose中间件所有这些都是可以避免的,你会带走更多的毫秒,但它仍然不是最糟糕的方式所以这是我的最小工作示例。
const http = require('http')
const mongoose = require('mongoose')
const redis = require('redis')
const port = 3000;
const util = require('util');
const client = redis.createClient()
client.get = util.promisify(client.get);
mongoose.connect('mongodb://localhost:27017/testdb', {useNewUrlParser: true});
const exec = mongoose.Query.prototype.exec;
var Schema = mongoose.Schema;
var testSchema = new Schema({
testfield: String, // String is shorthand for {type: String}
});
var Test = mongoose.model('Test', testSchema);
mongoose.Query.prototype.cache = function() {
this.useCache = true;
console.log("Setting CACHE to True")
return this;
}
mongoose.Query
.prototype.exec = async function () {
if (!this.useCache) {
console.log("GRABBING FROM DB")
console.log("CLIENT CONNECTION STATUS: " + client.connected);
return exec.apply(this, arguments);
}
console.log("ABOUT TO RUN A QUERY")
console.log("Query ==", this.getQuery())
console.log("Collection == ", this.mongooseCollection.name);
const key = JSON.stringify(Object.assign({}, this.getQuery(), {
collection: this.mongooseCollection.name
}));
//See if we have a value for 'key' in redis
console.log("KEY FROM QUERY AND COLLECTION",key);
const cacheValue = await client.get(key);
console.log("CACHE VALUE #1");
console.log(cacheValue);
//If we do, return that
if (cacheValue) {
console.log("cacheValue IS TRUE");
const doc = JSON.parse(cacheValue);
console.log("DOC == ",doc);
return Array.isArray(doc)
? doc.map(d => d)
: doc
// return exec( Array.isArray(doc)
// ? doc.map(d => new this.model(d))
//: new this.model(doc))
}
//Otherwise, issue the query and store the result in redis
const result = await exec.apply(this, arguments);
// console.log("EXEC === ", exec);
// console.log("result from query == ", result);
let redisData = JSON.stringify(result);
//stores the mongoose query result in redis
console.log("REDis data ===", redisData);
await client.set(key, redisData, function (err) {
console.error(err);
})
return result;
}
const server = http.createServer(function(req, res) {
if(req.url === '/'){
Test.find({}).cache().exec().then(function( docs) {
console.log("DOCS in response == ", docs);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(JSON.stringify(docs))
})
}
})
server.listen(port, function() {
console.log(`Server listening on port ${port}`)
})