TL; DR: 长时间运行的查询会终止其他用户的整个应用。绕过这个的策略是什么?
嗨,我在AWS T2.small实例(2GB,1核心)上运行MongoDB,用于流量较小的Meteor应用程序。它工作正常,除非人们想要运行一个报告来执行大约30个聚合以显示各种KPI。当一个用户运行报告(完成大约需要一分钟)时,应用程序性能很差(几乎为零),最糟糕的事情是其他人同时为自己的数据启动报告。然后他们甚至可能需要10分钟才能完成。 Web服务器的负载几乎为零并且不会导致问题,但MongoDB服务器的CPU在此类事件期间以100%运行(使用Meteor的unblock()执行所有单独的聚合调用不会提高性能)。
我知道我可以优化个别查询,或者我可以为更快的服务器支付更多费用,但这不是重点。如何阻止应用程序锁定(由于没有时间回复用户登录请求,用户甚至无法登录,因为数据库正忙)?我想要一些指导。
副本集会有帮助吗(例如隐藏的副本集成员)?我如何针对这一个实例进行报告(来自MeteorJS)?有没有办法为这些查询分配低优先级,只在服务器的空闲时间执行它们?
答案 0 :(得分:0)
看起来聚合查询对于服务器来说太过分了。如果它适用于您的用例,您可以创建预先汇总的报告。
预聚合报告的概念是,当您将新数据插入集合时,还会更新另一个集合中的“聚合文档”。例如,如果您的聚合需要某个字段的总值,则“聚合文档”中的sum
字段会将新文档的值添加到现有值。
使用预先聚合的报告将消除运行聚合查询的需要。相反,单个db.aggregates.find()
查询就足够了。
这种方法的一个缺点是,不需要单个插入操作,而是需要插入+更新。
请注意,如果预聚合方法不合适,那么将部署的配置增加到更大的计算机将是唯一现实的选择。
有关示例,请参阅https://docs.mongodb.com/ecosystem/use-cases/pre-aggregated-reports-mmapv1/。请注意,尽管技术细节是针对MMAPv1存储引擎的,但基础概念对于WiredTiger存储引擎同样有效。