我有一个包含 6000 只股票的 10M 文档的集合,股票名称被索引。当我订阅一只新股时,流星挂了10多秒,就得到了这只股票的大约3000份文件。同样在认购几只股票后,流星以 100% 的 cpu 使用率挂起。同步“大”集合时,流星看起来真的很慢。实际上我的应用程序只是只读的。我想知道是否有办法为只读客户端加速流星?我还想知道为每个库存创建单独的集合是否有帮助?
5 回答
Meteor 正在将整个数据集推送到您的客户端。
您可以通过删除自动发布包来关闭自动发布:
meteor remove autopublish
然后为您的客户创建特定的特定订阅。
当您订阅时,您可以将会话变量作为参数传递,因此在客户端上您可以执行以下操作:
sub = new Meteor.autosubscribe(function(){
Meteor.subscribe('channelname', getSession('filterval'));
}
在服务器上,您使用参数来过滤发送到客户端的结果集,这样您就不会一次通过管道传输所有内容。您可以使用过滤器以某种方式对数据进行分段。
Meteor.publish('channelname', function(filter){
return Collection.find({field: filter});
}
现在,每当您使用订阅更改客户端上的 filterval 时,setSession('filterval', 'newvalue');
都会自动更改,并且新数据集将发送到客户端。
您可以将其用作控制发送到客户端的数据量和数据量的一种方式。
正如另一位海报所说,你真的要问这是否是这项工作的最佳工具。Meteor 适用于在(可能)两个方向上实时更新的相对较小的数据集。它经过高度优化,并为该用例提供了大量的脚手架。
对于另一个用例(例如只读的巨大数据集),它可能没有意义。它有很多开销来提供您不会使用的功能,并且您将编写代码以获得您需要的功能。
我在同样的问题上苦苦挣扎。就我而言,我只需要同步大约 3000 条记录,总共大约 30KB。经过数周的尝试,我最终意识到同步不是问题,但似乎是同步时发生的 LiveHTML 更新。
通过在初始页面加载期间禁用模板更新,我能够将 300 条(过滤的)记录的页面加载时间从 10 秒减少到所有 3000 条记录的不到 2 秒。我通过向定义模板内容的函数添加条件来实现这一点:
之前(服务器发布 300 条记录的 10 秒页面加载):
Template.itemlist.items = function () {
return Item.find({type: 'car'},
{sort: {start: -1},
limit: 30});
};
到(服务器发布的 3000 条记录的 2 秒页面加载):
Template.itemlist.items = function () {
if (Session.get("active")) {
return Item.find({type: 'car'},
{sort: {start: -1},
limit: 30});
} else {
return [];
}
};
为了仅在加载数据后“激活”会话,我添加了:
Deps.autorun(function () {
Meteor.subscribe("Item",
{
onReady: function() {
Session.set("active", true);
}
});
});
虽然这是一个规模问题,可能可以改进;应该注意的是,您为您的任务使用了错误的技术,因为 Meteor 用于客户端之间的交互,而不是用于检索大量只读时间敏感数据。虽然状态跟踪屏幕可能仍然有些意义,但大量时间关键数据肯定不会......
整个 Meteor 堆栈比任何本机堆栈中的简单实现都引入了极大的开销;老实说,我什至会考虑 Java 或 C# 会引入的开销,并在选择 Java 或 C# 和 PHP 和 C++ 等低级语言时三思而后行。Ruby、Python、Node.js 等语言确实是另一回事。它们是为快速原型设计而设计的,但就延迟/吞吐量而言,由于 JIT 所需的开销,它们落后了,不要忘记一些非本地处理方法增加的开销。
TL;DR :使用正确的工具来完成这项工作,否则你会割伤你的手指......
启用自动发布后,您可能会看到 Mongodb 中大量文档的性能受到影响。您可以通过删除自动发布并编写代码以仅发布相关数据而不是整个数据库来解决此问题。
文档还涉及手动管理缓存:
复杂的客户端可以打开和关闭订阅,以控制在缓存中保留多少数据并管理网络流量。当订阅关闭时,它的所有文档都会从缓存中删除,除非另一个活动订阅也提供了相同的文档。
目前正在对 Meteor 进行其他性能改进,包括支持“非常大量的客户端”的 DDP 级代理。您可以在 Meteor路线图中查看更多详细信息。
我喜欢流星的简单。我只是停止使用本地 mongodb 集合以避免同步开销,性能看起来非常好。
Meteor.default_connection.registerStore "prices",
beginUpdate: ->
update: (msg) ->
updateChart(msg.set)
endUpdate: ->
reset: ->
对于新流星,以下作品。
Meteor.default_connection.registerStore collection,
constructor: (@update) ->
# Called at the beginning of a batch of updates.
beginUpdate: ->
update: (msg) ->
update(msg.fields, msg.id) if msg.fields
endUpdate: ->
reset: ->