如果用户有活动会话,MeteorJS 查询会非常慢
MeteorJS queries are super slow if users have active sessions
在我的 Meteor 应用程序中,我有一个对文档执行一些操作的函数。它首先获取数据,进行一些服务器端调整,然后再次更新文档属性。我有时需要 运行 它在很多文件上(数千,最多 250k)。
1000个文档正常速度在2s以内(一个一个的fetch文档,经过一些本地数据处理后,一个一个的更新;没有批量更新,所以运行还算快)。但是,如果网络服务器已经 运行ning 了一段时间,并且用户已登录,则需要永远 运行 此功能(例如,1000 个文档需要 160 秒)。
我必须注销所有用户 (db.users.update({}, {$set: {"services.resume.loginTokens": []}}, {multi: true}) ) 才能恢复速度.一旦我 运行 数据库查询,执行速度回到 ~2s/1000。
问题是什么?它不应该与索引相关,因为它会慢得多。此外,数据库端没有日志表明问题出在数据库上,并且数据库没有任何高 CPU 使用率。尽管网络服务器 运行 处于 100%(除此之外,网络服务器甚至从未达到 15%)。
网络服务器是 AWS T2.small 并且登录用户的数量(他们在晚上闲置)大约是 10 个。他们有一些公开订阅,我想。
听起来这是一个与观察者相关的问题,因为每个登录用户都可能订阅了正在更新的文档集。
我要尝试的第一件事是将操作作为 MongoDB Bulk Operation。这样所有文档都会立即更改,观察者和订阅将在更新完成后 运行 而不是在每次单独更改后。
示例 given in the Meteor guide 特定于 Todos 示例应用程序,但让您了解如何在 Meteor 中设置和运行 批量操作:
// This is how to get access to the raw MongoDB node collection that the Meteor server collection wraps
const batch = Lists.rawCollection().initializeUnorderedBulkOp();
//Mongo throws an error if we execute a batch operation without actual operations, e.g. when Lists was empty.
let hasUpdates = false;
Lists.find({todoCount: {$exists: false}}).forEach(list => {
const todoCount = Todos.find({listId: list._id}).count();
// We have to use pure MongoDB syntax here, thus the `{_id: X}`
batch.find({_id: list._id}).updateOne({$set: {todoCount}});
hasUpdates = true;
});
if(hasUpdates){
// We need to wrap the async function to get a synchronous API that migrations expects
const execute = Meteor.wrapAsync(batch.execute, batch);
return execute();
}
其他选项包括从数据处理中删除反应性,这样更新就不会全部自动发送到客户端。哪个比较复杂
在我的 Meteor 应用程序中,我有一个对文档执行一些操作的函数。它首先获取数据,进行一些服务器端调整,然后再次更新文档属性。我有时需要 运行 它在很多文件上(数千,最多 250k)。
1000个文档正常速度在2s以内(一个一个的fetch文档,经过一些本地数据处理后,一个一个的更新;没有批量更新,所以运行还算快)。但是,如果网络服务器已经 运行ning 了一段时间,并且用户已登录,则需要永远 运行 此功能(例如,1000 个文档需要 160 秒)。
我必须注销所有用户 (db.users.update({}, {$set: {"services.resume.loginTokens": []}}, {multi: true}) ) 才能恢复速度.一旦我 运行 数据库查询,执行速度回到 ~2s/1000。
问题是什么?它不应该与索引相关,因为它会慢得多。此外,数据库端没有日志表明问题出在数据库上,并且数据库没有任何高 CPU 使用率。尽管网络服务器 运行 处于 100%(除此之外,网络服务器甚至从未达到 15%)。
网络服务器是 AWS T2.small 并且登录用户的数量(他们在晚上闲置)大约是 10 个。他们有一些公开订阅,我想。
听起来这是一个与观察者相关的问题,因为每个登录用户都可能订阅了正在更新的文档集。
我要尝试的第一件事是将操作作为 MongoDB Bulk Operation。这样所有文档都会立即更改,观察者和订阅将在更新完成后 运行 而不是在每次单独更改后。
示例 given in the Meteor guide 特定于 Todos 示例应用程序,但让您了解如何在 Meteor 中设置和运行 批量操作:
// This is how to get access to the raw MongoDB node collection that the Meteor server collection wraps
const batch = Lists.rawCollection().initializeUnorderedBulkOp();
//Mongo throws an error if we execute a batch operation without actual operations, e.g. when Lists was empty.
let hasUpdates = false;
Lists.find({todoCount: {$exists: false}}).forEach(list => {
const todoCount = Todos.find({listId: list._id}).count();
// We have to use pure MongoDB syntax here, thus the `{_id: X}`
batch.find({_id: list._id}).updateOne({$set: {todoCount}});
hasUpdates = true;
});
if(hasUpdates){
// We need to wrap the async function to get a synchronous API that migrations expects
const execute = Meteor.wrapAsync(batch.execute, batch);
return execute();
}
其他选项包括从数据处理中删除反应性,这样更新就不会全部自动发送到客户端。哪个比较复杂