Meteor 失去与数据库的连接

Meteor loses connection to the database

我正在 运行在 Digital Ocean 上创建一个 Meteor 实例,并在 Mongolab 上托管 Mongo 数据库。如果站点闲置了几个小时,并且有人访问了特定页面,Meteor 似乎会断开与数据库的连接 3-15 分钟,没有任何错误或任何警告。这是我能够弄清楚的:

DigitalOcean 上的 Meteor 服务器

Mongo实验室 MongoDB

我怀疑它与以下出版物有关:

Meteor.publish('spaceUtilSpace', function(view_id, space_id){
  if(!checkSpaceUtilPermissions(view_id, "View Reader", this.userId)) { this.ready(); return; }

  var thisUser = Meteor.users.findOne({_id: this.userId});
  var thisView = View_SpaceUtil.findOne({_id: view_id});

  if(thisView){
    var thisSpace = Spaces.findOne({_id: space_id});

    return [
      View_SpaceUtil.find({_id: view_id}),
      Bldgs.find({_id: thisSpace.localID.bldg_id}),
      Spaces.find({_id: space_id}),
      Schedule.find({"localID.space_id":space_id, startDateMs:{$lte:thisView.time.toDate}, endDateMs:{$gte:thisView.time.fromDate}})
    ]
  }
})

我怀疑问题最有可能出在这一行: Schedule.find({"localID.space_id":space_id, startDateMs:{$lte:thisView.time.toDate}, endDateMs:{$gte:thisView.time.fromDate}}),因为这是我最大的 collection(约 80,000 个文档,150 MB)。

起初我以为我可能只需要这个查询的索引,处理这个特定查询的时间太长了,但是在为 {"localID.space_id":1, startDateMs:-1, endDateMs:1} 创建索引后,我仍然有同样的问题。

关于如何解决这个问题,我开始 运行 缺乏想法,所以任何建议都会非常有帮助。谢谢!

更多信息

通过 Mongo 日志,我发现了以下两行:

2015-12-04T08:11:09.904-0800 I QUERY    [conn51589] query myDatabase.schedule query: { localID.space_id: "mjEYjonRaFrrr8gcX", startDateMs: { $lte: 1451520000000.0 }, endDateMs: { $gte: 1262304000000.0 } } planSummary: COLLSCAN ntoreturn:0 ntoskip:0 nscanned:0 nscannedObjects:78172 keyUpdates:0 writeConflicts:0 numYields:6664 nreturned:0 reslen:20 locks:{ Global: { acquireCount: { r: 13330 } }, MMAPV1Journal: { acquireCount: { r: 6665 } }, Database: { acquireCount: { r: 6665 } }, Collection: { acquireCount: { R: 6665 } } } 232971ms
2015-12-04T08:11:10.429-0800 I QUERY    [conn51593] query myDatabase.schedule query: { localID.space_id: "mjEYjonRaFrrr8gcX", startDateMs: { $lte: 1451520000000.0 }, endDateMs: { $gte: 1262304000000.0 } } planSummary: COLLSCAN ntoreturn:0 ntoskip:0 nscanned:0 nscannedObjects:78172 keyUpdates:0 writeConflicts:0 numYields:610 nreturned:0 reslen:20 locks:{ Global: { acquireCount: { r: 1222 } }, MMAPV1Journal: { acquireCount: { r: 611 } }, Database: { acquireCount: { r: 611 } }, Collection: { acquireCount: { R: 611 } } } 128ms

问题似乎是一个查询需要很长时间才能完成,并且在完成之前不允许进行新的查询。

这两个让我感到困惑的是查询本身是相同的,但是第一个的 'acquireCount' 有 10 倍的内容,并且花了大约 2000 倍的时间才达到 return。这些字段已编入索引...关于为什么会发生这种情况的任何想法?

在与 Mongolab 支持人员讨论后,我得到了答案(可能)。

我使用的是共享集群计划,因此如果一个查询 运行 几个小时没有出现,它就会从内存中清除,以允许其他用户访问该块。下一次查询是 运行,它必须将该数据重新加载到内存中,在本例中这花费了很长时间。我重新评估了我的索引策略,我发现我错过了我应该拥有的索引——我已经索引 "localID.bldg_id",但忘记做一个单独的索引,其中包括 "localID.space_id" ,这是这个问题的重要问题。

我必须等到内存刷新后才能验证此解决方案是否有效,但看起来很有可能。

如果没有,Mongolab 的建议是移动到专用集群,而不是使用共享集群。