是否在MongoDB中动态创建和删除集合会产生可伸缩性问题?

时间:2016-10-29 13:17:41

标签: mongodb meteor

我有一个应用程序(内置Meteor),可为最终用户提供一些临时报告功能。我通过使用聚合管道为给定查询生成结果来构建该功能。这使得它非常快,我使用$out将结果直接推送到结果表中。

结果表包含一个queryID,客户端用它来确定哪些是正确的结果。

不幸的是,正如您可能知道的(我发现),一旦您有多个用户一次运​​行报告,这种方法效果不佳,因为$out在推送​​新查询之前会删除整个结果表英寸

我看到了三种可能的解决方法:

  1. 运行聚合,但手动将结果推送到结果集合
  2. $out将结果转换为临时集合(动态命名以避免冲突),然后手动将结果从那里复制到结果集合中,立即删除临时集合。当我认为我可以使用copyTo()时,这是有道理的,但这在Meteor中似乎不可能,所以我认为这个选项在这种情况下相对于#1没有多大意义。
  3. $out将结果转换为临时集合(动态命名以避免冲突)并让客户端直接从中获取结果。然后我会在24小时之后定期删除额外的集合(就像我今天在主集合中使用特定查询结果一样)。
  4. 到目前为止,#3将是最快的 - 手动复制行所花费的时间使查询运行所花费的时间相形见绌。但是我担心创建和删除这么多集合的影响。

    我们这里并没有谈论数百万用户,但如果平均每天有500名用户运行10-20个报告,那么任何时候数据库中都可能会有额外的5-10k个收集。这似乎很多。也许我可以更聪明地以某种方式清理它们,虽然我不能立即删除它们,因为用户可能希望打开不同报告的多个选项卡。即便如此,我们仍有可能谈论成千上万的收藏品。

    这会成为一个问题吗?

    我还应该考虑其他方法吗?

    其他建议?

    谢谢!

2 个答案:

答案 0 :(得分:1)

删除mongoDB中的集合是非常有效的操作,无论如何比删除更大集合中的某些文档更有效。 最大集合数量非常高,仅受MMAPv1中名称空间namespace的限制,而wiretiger引擎中没有硬限制。 所以我赞成你的解决方案#3。 您可以想到一些改进/替代方案:

  1. 考虑在分离的数据库中创建集合(比如每天),然后您可以在一个操作中删除整个数据库,而不必删除单个集合。
  2. 使用端点作为结果集,兑现结果,然后删除$ out集合。让缓存处理用户需求,只有在缓存过期或其他情况下才重新运行聚合。

答案 1 :(得分:0)

这种活动在关系数据库(如mysql或pgsql)中非常容易完成。您可以考虑将数据同步到单独的关系数据库以进行报告。

有一个声明提供同步的包https://github.com/perak/mysql-shadow。我玩它并且它没有完美地工作,尽管只做一次同步更有可能成功。

另一种选择是在mongo / mysql混合数据库上使用Graphql,这可以通过Apollo堆栈来完成http://www.apollodata.com/