在我的Meteor应用中,用户可以互相关注。当一个用户跟随另一个用户时,需要在MongoDB上运行多个操作,因此跟随操作本身并不是完全原子的。如果服务器在执行中期崩溃,则用户配置文件中的虚荣计数表示他或她关注的用户数,即"following": 24
可能实际上与您直接查找的数量不匹配在MongoDB的followers
集合中存储关系数据。
为了缓解这个问题,让我们说,每隔24小时,午夜,我会安排一个cron作业,查找MongoDB中的每个user
文档,并根据数据验证文档的完整性来自其他系列。如果用户文档中的数据准确无误,那么它就是noop
并继续下一个用户文档。如果任何计数已关闭,请在继续下一个用户之前更正它们。
我的问题是:你如何有效地实施这种CRON工作?假设我在Meteor应用上拥有100,000个注册用户。如果我做了Meteor.users.find().fetch()
,我会在开始迭代之前将100k用户文档加载到RAM中。随着用户群的增长,问题会更加复杂,这就像服务器崩溃等待发生一样。
确保处理所有用户文档的最佳方法是什么,同时有效地处理,而不是完全锁定Meteor服务器,以便它仍然可以响应来自Web前端的用户请求?< / p>
答案 0 :(得分:2)
假设我在Meteor应用上拥有100,000个注册用户。如果我做了 Meteor.users.find()。fetch(),我将加载100k用户文档 在我开始迭代之前的RAM。
有两件事。
首先,您可以通过在find方法中使用投影来减少加载的数据:
db.collection.find(query, projection)
https://docs.mongodb.com/manual/reference/method/db.collection.find/
此投影包含与您相关的字段的名称。 Mongo只返回游标,包含带有这些字段的文档。这可能会将数据量减少到最低限度。
一个例子是:
Meteor.users.find({},{following:1).fetch()
此查询会查找“所有”用户,但仅返回带有“跟随”字段的文档。
第二件事。
调用.find().fetch()
会将您的mongo游标转换为数组,您必须逐步迭代此数组。
由于您在服务器cli上工作(您可以将mongo的api排到最大),您可能更喜欢使用光标级别。它提供了许多迭代和操作数据的方法:
https://docs.mongodb.com/manual/reference/method/js-cursor/
第三件事:
无论如何,你使用游标oder数组(fetch)解决方案:你可能会尝试实现一个延迟加载机制。因此,您可以只处理新文档的块,而不是整个队列。因此,您保证,其他东西总是有空间(RAM)。
https://en.wikipedia.org/wiki/Lazy_loading
如果您对这些建议有任何疑问,请与我们联系。