写入问题的缓慢upsert是否未被确认,并且许多产量表明我的查询存在问题?

时间:2014-07-22 08:17:30

标签: mongodb

我正在为一个收集很多查询的集合做很多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

1 个答案:

答案 0 :(得分:0)

写入确认或“写入关注”不会影响整体查询性能,实际上是客户端等待确认时可能采取的时间。因此,如果您或多或少处于“即发即忘”模式,那么您的客户端不会被阻止,但写操作仍然可以暂时使用。

在这种情况下,您的工作集似乎实际上非常大。值得考虑的是,这是“服务器范围”,而不仅仅局限于一个集合甚至数据库。这里的一般情况是你没有足够的RAM用于你正在尝试加载的内容并且你正在进行分页。请参阅“收益率”计数器。

Upserts需要在索引中“找到”匹配的文档,因此即使没有匹配,您仍然需要“扫描”并查明该项是否存在。这意味着将索引加载到内存中。因此,您有几个选择:

  1. 改造使这些写入“仅插入”,并在后台进程中聚合“计数器”类型值,但基本上不是实时的。

  2. 在您的手段中添加更多内存。

  3. 分片时间,这样您就可以在群集中拥有多个“分片”,这些分片具有足够的RAM来处理工作集大小。

  4. 这里没有什么比这更容易了,根据您的应用实际需要,所有提供不同级别的解决方案。实际上,如果你准备好在没有“写入确认”的情况下生活,那么你可能需要解决你的应用程序的其余部分,并且实际上可以读取这些写入的“最终一致性”。