Vil*_*tor 5 performance amazon-ec2 mongodb amazon-web-services
FETCH阶段是我的查询中的限制因素.我一直在研究,似乎mongodb读取的内容远远超过它的需要,并且没有充分利用带宽.
我的mongoDB-mongod实例似乎在一个查询上阅读很多.使用1个EBS io 5000Piops附加(100GB)SSD在AWS EC2 m4.xlarge上进行测试.16 GB内存.
db stats
db.stats()
{
"db" : "database",
"collections" : 4,
"objects" : 406496932,
"avgObjSize" : 326.3196544642064,
"dataSize" : 132647938391,
"storageSize" : 55475830784,
"numExtents" : 0,
"indexes" : 5,
"indexSize" : 8940408832,
"ok" : 1
}
Run Code Online (Sandbox Code Playgroud)
收集摘要:
db.collection.stats() ->
{ "ns" : "database.[collection###]",
"count" : 367614513,
"size" : 121155225858,
"avgObjSize" : 329,
"storageSize" : 52052197376,
"capped" : false,
"wiredTiger" : {"Left empty"},
"nindexes" : 2,
"totalIndexSize" : 8131604480,
"indexSizes" : {
"_id_" : 4373012480,
"id_1_ts_-1" : 3758592000
},
"ok" : 1
Run Code Online (Sandbox Code Playgroud)
查询:
db.[#######].find({ id : "######",
ts : {
"$gte" :
ISODate("2016-10-01T00:00:00.000Z"),
$lt :
ISODate("2016-10-07T02:00:00.000Z")
}}, {_id : 0,"u1"
:1,"u2":1,"u3":1,"eq1" :1 ,"eq2" : 1,"eq3": 1,"ts" :1});
Run Code Online (Sandbox Code Playgroud)
并解释结果:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "database.[collection]",
"d" : false,
"parsedQuery" : {
"$and" : [
{
"id" : {
"$eq" : "#####ID#####"
}
},
{
"ts" : {
"$lt" : ISODate("2016-09-30T22:00:00Z")
}
},
{
"ts" : {
"$gte" : ISODate("2016-09-22T22:00:00Z")
}
}
]
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 0,
"u1" : 1,
"u2" : 1,
"u3" : 1,
"eq1" : 1,
"eq2" : 1,
"eq3" : 1,
"ts" : 1
},
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"id" : 1,
"ts" : -1
},
"indexName" : "id_1_ts_-1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[\"#####ID#####\", \"#####ID#####\"]"
],
"ts" : [
"(new Date(1475272800000), new Date(1474581600000)]"
]
}
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 676745,
"executionTimeMillis" : 170508,
"totalKeysExamined" : 676745,
"totalDocsExamined" : 676745,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 676745,
"executionTimeMillisEstimate" : 167820,
"works" : 676746,
"advanced" : 676745,
"needTime" : 0,
"needYield" : 0,
"saveState" : 8970,
"restoreState" : 8970,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"_id" : 0,
"u1" : 1,
"u2" : 1,
"u3" : 1,
"eq1" : 1,
"eq2" : 1,
"eq3" : 1,
"ts" : 1
},
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 676745,
"executionTimeMillisEstimate" : 166470,
"works" : 676746,
"advanced" : 676745,
"needTime" : 0,
"needYield" : 0,
"saveState" : 8970,
"restoreState" : 8970,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 676745,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 676745,
"executionTimeMillisEstimate" : 980,
"works" : 676746,
"advanced" : 676745,
"needTime" : 0,
"needYield" : 0,
"saveState" : 8970,
"restoreState" : 8970,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"id" : 1,
"ts" : -1
},
"indexName" : "id_1_ts_- 1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"id" : [
"[\"#####ID#####\", \"#####ID#####\"]"
],
"ts" : [
"(new Date(1475272800000), new Date(1474581600000)]"
]
},
"keysExamined" : 676745,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"allPlansExecution" : [ ]
},
"serverInfo" : {
"host" : "ip #########",
"port" : 27017,
"version" : "3.2.10",
"gitVersion" : "79d9b3ab5ce20f51c272b4411202710a082d0317"
},
"ok" : 1
Run Code Online (Sandbox Code Playgroud)
}
正如我们在上面看到的,mongoDb使用索引.IXSCAN需要980ms,FETCH 需要16,000ms.
如果我不误认为整个读取应该是676746(nReturned)*329(avgObjSize)Bytes = ~212 MB的数据.
我注意到在iostats(http://linuxcommand.org/man_pages/iostat1.html)中有以下内容(/ data/db在xvdf上):
vg-cpu: %user %nice %system %iowait %steal %idle
0.27 0.00 0.00 21.35 0.13 78.25
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
xvda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
xvdf 0.00 0.00 1691.00 0.00 19.83 0.00 24.02 0.95 0.56 0.56 0.00 0.56 94.40
Run Code Online (Sandbox Code Playgroud)
在整个操作(获取阶段)期间,rMB/s表示~20MB/s并且这是连续的.这意味着mongodb正在读取160 s*20MB/s = 3 200 MB,这超过了200 MB以上.
记忆:
free -m
total used free shared buffers cached
Mem: 16048 12629 3418 0 32 4071
-/+ buffers/cache: 8525 7522
Swap: 0 0
Run Code Online (Sandbox Code Playgroud)
mongodb还没有使用配置的5000 iops EBS,也没有承诺带宽?仅使用~1700读/秒导致~20MB/s.
我已将预读更改为16KB.我曾尝试将日志和日志放在另一个硬盘上.
我想不出来了!帮我.请!
小智 6
我在获取大约 35000 个文档时遇到了同样的问题。为了解决这个问题,我使用了聚合函数 ( sakulstra:aggregate),在我的例子中,它极大地提高了请求。结果格式显然不一样,但它仍然很容易用来计算我需要的所有东西。
之前(7000 毫秒):
const historicalAssetAttributes = HistoricalAssetAttributes.find({
date:{'$gte':startDate,'$lte':endDate},
assetId: {$in: assetIds}
}, {
fields:{
"date":1,
"assetId":1,
"close":1
}
}).fetch();
Run Code Online (Sandbox Code Playgroud)
之后(300 毫秒):
const historicalAssetAttributes = HistoricalAssetAttributes.aggregate([
{
'$match': {
date: {'$gte': startDate, '$lte': endDate},
assetId: {$in: assetIds}
}
}, {
'$group':{
_id: {assetId: "$assetId"},
close: {
'$push': {
date: "$date",
value: "$close"
}
}
}
}
]);
Run Code Online (Sandbox Code Playgroud)
主要事实是:
假设 WiredTiger 缓存设置为默认值,为 WiredTiger 缓存保留的 RAM 量应约为 8.6 GB。在https://docs.mongodb.com/v3.2/faq/storage/#to-what-size-should-i-set-the-wiredtiger-internal-cache 中:
从 MongoDB 3.2 开始,默认情况下 WiredTiger 内部缓存将使用较大者:
- 60% 的 RAM 减去 1 GB,或
- 1 GB。
从上面的信息来看,你的机器似乎存在内存压力。MongoDB 尝试将索引保留在内存中以便快速访问,整个索引约为 7 GB。这将仅用索引有效地填充大约 80% 的 WiredTiger 缓存,为其他任何东西留下很少的空间。结果,MongoDB 被迫从磁盘中提取结果集中的文档。在这一点上,性能受到影响。
您可以从iostat输出中看到此效果,其中设备xvdf(数据所在的位置)的利用率超过 94%(显示在%util列中),这意味着您的操作受 I/O 限制,因为您没有足够的资源RAM 来满足您理想的工作集。
为了缓解这个问题,您可以尝试:
| 归档时间: |
|
| 查看次数: |
1851 次 |
| 最近记录: |