【问题标题】:Meteor loses connection to the databaseMeteor 失去与数据库的连接
【发布时间】:2015-12-04 17:00:48
【问题描述】:

我正在 Digital Ocean 上运行 Meteor 实例,并在 Mongolab 上托管 Mongo 数据库。如果站点空闲了几个小时,并且有人转到特定页面,Meteor 似乎会在 3-15 分钟内断开与数据库的连接,而不会出现任何错误或警告。以下是我能够弄清楚的:

DigitalOcean 上的 Meteor 服务器

  • 继续运行,Meteor.status() 显示活动连接
  • 剧集中 CPU 负载下降
  • 将继续提供网络应用的副本。

Mongolab 上的 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}}),因为这是我最大的集合(约 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 倍的时间才能返回。这些字段被编入索引......关于为什么会发生这种情况的任何想法?

【问题讨论】:

  • 我没用过Mongolab,所以不知道他们给你什么样的分析。希望他们有一些显示查询性能测量的东西 - 如果没有,您可以使用 Kadira 或 MongoDB 分析来确定这个特定查询(或其他查询)是否会产生问题。我自己没有遇到过这个问题,所以我无能为力 - 但我倾向于认为这很可能是数据库方面的问题,而不是任何事情(其他选项是 Meteor 或网络问题)。
  • 另外,非常重要:当有人访问一个非常具体的页面时会发生这种情况,对吗?在此之前数据库性能还可以(即至少没有“死”)?然后肯定是某些特定的查询会出现问题。使用 MongoDB 分析或 Mongolab 分析或 Kadira 找出它是哪个查询,然后将您的问题缩小到仅此一个查询,并提供有关集合等的更多详细信息。这样更容易提供帮助。
  • 你好,奥斯卡。谢谢,我一直在查看 Kadira 没有太多运气,但是通过数据库日志我发现了问题查询,这是我认为的问题......但我仍然不太确定发生了什么.我已经编辑了我的问题以包含新信息。
  • 我没有足够的信息来说明为什么会发生这种情况。索引{"localID.space_id":1, startDateMs:1, endDateMs:-1} 应该更好,但索引可能根本不是造成这种情况的原因。 This article 将帮助您分析您的查询。另请查看页面底部另请参阅部分中的文章。
  • 感谢您的反馈和指导。

标签: mongodb meteor database-connection mlab


【解决方案1】:

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

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

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

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

【讨论】:

  • 嗯,很有趣。感谢您提供的信息,这实际上非常有用。在为我的下一个项目选择数据库提供程序时,我会牢记这一点。
  • 很高兴为您提供帮助,感谢您帮助我解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-12
  • 1970-01-01
  • 2021-02-22
  • 2016-09-24
  • 2016-10-01
  • 1970-01-01
相关资源
最近更新 更多