我正在一个有超过25,000个用户的项目中,每次为Oppurtinity module
创建任何记录时,它都会执行此功能,该功能会在mongodb中为每个用户插入通知详细信息,
问题在于它占用了cpu,并且不让任何其他API产生结果,直到此异步结束为止,这会占用时间,同时服务器不会加载任何其他数据/它会给出较晚的响应。
v10.15.3
v4.0.17
Memory-8GB
2.70GHz speed
我想知道,这里的问题是什么,代码是什么,如果可以的话,我该如何优化它?
async.eachSeries(users, (eachuser, next) => {
db.notifications.find({user_id:eachuser._id},function(errr,opp_noti){
if(opp_noti.length != 0){
db.notifications.update( { user_id:eachuser._id},{$push:{oppurtunity:oppurtunity_id}},function(errr,result){
})
}else{
db.notifications.insert({user_id:eachuser._id,oppurtunity:[oppurtunity_id]},function(errr,result){
})
}
})
next();
})
最佳答案
您的示例代码和您的问题有一些问题。我必须假设您正在使用以下库:Async和MongoDB。请尝试更好地整理您的问题。
如果我假设正确,则由于未正确实现async.eachSeries
函数,因此您没有仔细阅读文档-eachSeries
期望async
函数作为第二个参数。
我已经基于这两个库的文档重写了您的代码。我以前从未使用过它们,但我有把握地确信它是正确的。
async.eachSeries(users, async (user) => {
const user_id = user._id;
const cursor = db.notifications.find({ user_id });
const count = await cursor.count();
if (count > 0) {
return db.notifications.update({ user_id },
{
$push: { oppurtunity: oppurtunity_id } // where is oppurtunity_id defined?
}
)
} else {
return db.notifications.insert({
user_id,
oppurtunity: [oppurtunity_id]
})
}
})
您可能已经意识到这一点,但是async.eachSeries
将通过依次运行它们来限制请求。尽管出于各种原因这可能是必需的,但它会减慢该过程,并且不会利用Node的非阻塞性质。 async.each
将并行运行它们,这在理论上是最快的,但是在25K记录下可能会引起问题。因此,我建议您采取中间立场,并考虑使用async.eachOfLimit
,设置并行限制并查看其性能。您也可以通过不查询每个用户的数据库来进一步解决该问题并获得显着的性能提升。尝试在一个查询中让所有需要提前更新的用户。
类似于以下内容的内容将在一个查询中返回
notifications
集合中的所有ID(可能在底层查询中返回多个ID,但仍比n好得多)。const user_ids = db.notifications.find({}, { _id:1 }).map(item => item._id)
一旦有了ID,就可以创建两个工作负载,一个工作负载来运行所有db.notifications.update
查询,另一个工作负载来运行所有db.notifications.insert
查询。
关于node.js - 优化异步查询 Node ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65231833/