我正在为一个收集很多查询的集合做很多upsert。我的upserts一直没有得到承认。许多这些upserts出现在mongo日志中,运行时间超过800毫秒,收益率超过20.服务器上的inprog操作数量似乎稳定在20左右,峰值在40左右。
该集合包含约1,500万份文件。
这些长查询时间是否表明mongo服务器无法跟上传入数据,或者只是以受控方式推迟未确认的查询?
集合中的文档如下所示:
{
"_id" : ObjectId("53c65f9f995bce51e4d84ecb"),
"items" : [
"53216cf7e4b04d3fa854a4d0",
"53218be4e4b0a79ba7fee19a"
],
"score" : 1,
"other" : [
"b09b2c99-e4f3-48a2-990d-4b2090cc9666",
"b09b2c99-e4f3-48a2-990d-4b2090cc9666"
]
}
我有以下索引
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "dbname.stuff"
},
{
"v" : 1,
"key" : {
"items" : 1,
"score" : -1
},
"name" : "items_1_score_-1",
"ns" : "dbname.stuff",
"background" : true
}
]
慢速upserts在日志
中看起来像这样update dbname.stuff query: { items: [ "52ea4da1e4b035b15423f8f5", "53c7cf43e4b007135ca60114" ] } update: { $inc: { score: 6 }, $setOnInsert: { others: [ "64a7e6b1-2a0a-4374-ac9c-fbf2de7cbb48", "b9e07cda-14c8-45e4-95cc-f0f4c5bc410c" ] } } nscanned:0 nscannedObjects:0 nMatched:1 nModified:0 fastmodinsert:1 upsert:1 keyUpdates:0 numYields:16 locks(micros) w:46899 1752ms
答案 0 :(得分:0)
写入确认或“写入关注”不会影响整体查询性能,实际上是客户端等待确认时可能采取的时间。因此,如果您或多或少处于“即发即忘”模式,那么您的客户端不会被阻止,但写操作仍然可以暂时使用。
在这种情况下,您的工作集似乎实际上非常大。值得考虑的是,这是“服务器范围”,而不仅仅局限于一个集合甚至数据库。这里的一般情况是你没有足够的RAM用于你正在尝试加载的内容并且你正在进行分页。请参阅“收益率”计数器。
Upserts需要在索引中“找到”匹配的文档,因此即使没有匹配,您仍然需要“扫描”并查明该项是否存在。这意味着将索引加载到内存中。因此,您有几个选择:
改造使这些写入“仅插入”,并在后台进程中聚合“计数器”类型值,但基本上不是实时的。
在您的手段中添加更多内存。
分片时间,这样您就可以在群集中拥有多个“分片”,这些分片具有足够的RAM来处理工作集大小。
这里没有什么比这更容易了,根据您的应用实际需要,所有提供不同级别的解决方案。实际上,如果你准备好在没有“写入确认”的情况下生活,那么你可能需要解决你的应用程序的其余部分,并且实际上可以读取这些写入的“最终一致性”。