Meteor 失去与数据库的连接
Meteor loses connection to the database
我正在 运行在 Digital Ocean 上创建一个 Meteor 实例,并在 Mongolab 上托管 Mongo 数据库。如果站点闲置了几个小时,并且有人访问了特定页面,Meteor 似乎会断开与数据库的连接 3-15 分钟,没有任何错误或任何警告。这是我能够弄清楚的:
DigitalOcean 上的 Meteor 服务器
- 继续 运行,
Meteor.status()
显示活动连接
- CPU 一集中负载下降
- 将继续提供网络应用程序的副本。
Mongo实验室 MongoDB
- 查询操作下降到 almost-zero
- 页面错误激增
- Network-out 流量降为零。
- 仍可直接访问查询
- 使用相同数据库的其他服务器(worker)照常进行。
我怀疑它与以下出版物有关:
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 的建议是移动到专用集群,而不是使用共享集群。
我正在 运行在 Digital Ocean 上创建一个 Meteor 实例,并在 Mongolab 上托管 Mongo 数据库。如果站点闲置了几个小时,并且有人访问了特定页面,Meteor 似乎会断开与数据库的连接 3-15 分钟,没有任何错误或任何警告。这是我能够弄清楚的:
DigitalOcean 上的 Meteor 服务器
- 继续 运行,
Meteor.status()
显示活动连接 - CPU 一集中负载下降
- 将继续提供网络应用程序的副本。
Mongo实验室 MongoDB
- 查询操作下降到 almost-zero
- 页面错误激增
- Network-out 流量降为零。
- 仍可直接访问查询
- 使用相同数据库的其他服务器(worker)照常进行。
我怀疑它与以下出版物有关:
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 的建议是移动到专用集群,而不是使用共享集群。