我有一个 Express 应用程序,它需要非常低的响应率 ~<200 毫秒。现在我们只能得到这个数字,但这是一个单独的话题。
我们计划从数据库中获取一段数据,如果在 Redis 中找到,则返回数据,如果没有,则触发请求并将其保存到 Redis,以便下一个请求可以从 Redis 中获取它。
我正在运行一些测试,想知道是否有办法减少数据库获取请求的数量?
例如,目前我们的应用程序每个盒子有 300req/s。我们有六个盒子在 AWS 上运行。如果那条数据第一次在 Redis 中不可用,可能会有大约 500 个请求试图从数据库中获取数据并将其缓存在 Redis 中。我们正在努力减少这个数字。不确定 Node.js 或 Redis 中是否有处理该问题的方法。
这是我正在测试的代码。
client.getAsync('key').then(function (data) {
if(data) {
console.log(data); // Return this data if found
res.send(data);
} else {
// I'm trying to reduce the number of calls for concurrent requests in this block.
console.log('not found');
var dataFromDb = // fetch data from DB
client.set('key', dataFromDb); // Fire and forget
res.send('not found'); // Return not found right away
}
});
然后我使用 ab
ab -n 20 -c 10 http://localhost:8081/redis
这是我得到的结果
not found
not found
not found
not found
not found
not found
something
not found
something
something
something
something
something
something
something
something
something
something
在这个例子中,有 7 个请求试图获取具有相同数据的数据库并保存到 Redis。
我的问题是,无论如何我可以减少请求的数量吗?因为目前获取 DB 非常慢 ~900ms(我们正在尝试优化它)
最佳答案
是的。我做了同样的事情。我将在这里只描述逻辑。 fetchCache 的方法应该返回一个 promise 。您还保留 { cacheKey, promise } 数组。每次发送请求时,您都会向该数组添加键。下次你需要获取缓存时 - 你首先检查数组,如果那里有关键,则捕获这个 promise 。否则调用 fetchCache。
这是我的代码。它有效,但可能难以阅读。应该让您有一个基本的了解。
class DictTranslatableRepo {
constructor(model) {
var self = this;
self.title = model + "s Repo";
self.model = models[model];
self.running = {};
self.curItems = {};
}
*start() {
var self = this;
var curItems = yield self.model.findAll();
_.forEach(curItems, function(row) {
self.curItems[row.key] = row.value;
});
};
*map(from) {
var self = this;
if (from == "") return "";
if (!_.isUndefined(self.curItems[from])) return self.curItems[from];
if (_.isUndefined(self.running[from])) {
self.running[from] = [];
return new Promise(function(resolve, reject) {
self.running[from].push(resolve);
self.job(from, function(err, to) { // Main job
var callbackArr = self.running[from];
delete self.running[from];
_.forEach(callbackArr, function(callback) {
callback(to);
});
});
});
} else {
return new Promise(function(resolve, reject) {
self.running[from].push(resolve);
});
}
};
job(from, callback) {
var self = this;
var to = "as shown";
co(function*() {
try {
to = yield translator.translate(from);
yield self.model.add({key: from, value: to});
self.curItems[from] = to;
callback(null, to);
} catch (err) {
callback(err);
//logger.error("Cant translate entity: " + from);
}
}).catch(function(err) {
// Unhandled Error
callback(new Error(err));
});
};
}
我的 map
方法是您的 fetchCache 方法。
关于node.js - 有什么方法可以减少在 nodejs 中获取数据和缓存的并发请求量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35950293/