如何提高MongoDB插入性能

时间:2015-07-08 16:21:10

标签: c# performance mongodb mongodb-.net-driver

结果:

如果您正在对容错的数据集进行操作,或者执行一次性过程,则可以进行验证,将WriteAcknowledge更改为Unacknowledged可以提供帮助。

此外,默认情况下,批量操作是IsOrdered,我不知道。将此设置为False实际上会使操作批量执行,否则它将作为一个更新线程运行。

MongoDB 3.0 / WiredTiger / C#驱动程序

我有一个包含147,000,000个文档的集合,其中我每秒钟(希望)大约会执行更新。 3000份文件。

以下是更新示例:

"query" : {
    "_id" : BinData(0,"UKnZwG54kOpT4q9CVWbf4zvdU223lrE5w/uIzXZcObQiAAAA")
},
"updateobj" : {
    "$set" : {
        "b" : BinData(0,"D8u1Sk/fDES4IkipZzme7j2qJ4oWjlT3hvLiAilcIhU="),
        "s" : true
    }
}

这是一个典型的更新,我的要求是以每秒3000的速度插入。

不幸的是,这些花费的时间是原来的两倍,例如最后一次更新是针对1723个文档,并且需要1061ms。

集合只有_id的索引,没有其他索引,集合的平均文档大小是244字节,没有上限。

服务器有64GB内存,12个线程。插入性能非常好,收集尺寸较小,比如大约5000万,但是大约有8000万之后真正开始下降。

可能是因为整套不在内存中吗?数据库由RAID0 SSD支持,因此IO性能不应成为瓶颈,如果它应该在一开始就显示出来了吗?

我很欣赏一些指导,因为我相信MongoDB可以满足我的相当微薄的要求,而不是它所使用的一些应用程序。数据库没有大量的读取率,所以Sharding不会改善问题,尽管可能我错了

无论哪种方式,目前的插入率都不够好。

更新:以下是查询的解释()...

"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "Collection",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "_id" : {
            "$eq" : { "$binary" : "SxHHwTMEaOmSc9dD4ng/7ILty0Zu0qX38V81osVqWkAAAAAA", "$type" : "00" }
        }
    },
    "winningPlan" : {
        "stage" : "IDHACK"
    },
    "rejectedPlans" : []
},
"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 1,
    "totalKeysExamined" : 1,
    "totalDocsExamined" : 1,
    "executionStages" : {
        "stage" : "IDHACK",
        "nReturned" : 1,
        "executionTimeMillisEstimate" : 0,
        "works" : 2,
        "advanced" : 1,
        "needTime" : 0,
        "needFetch" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 1,
        "invalidates" : 0,
        "keysExamined" : 1,
        "docsExamined" : 1
    },
    "allPlansExecution" : []
},

它自身的查询速度非常快,更新操作大约需要25毫秒,使用BulkWriter将它们推送到Mongo:await m_Collection.BulkWriteAsync(updates);

4 个答案:

答案 0 :(得分:13)

您可以尝试修改Write concern levels。 显然存在风险,因为您无法捕获任何写入错误,但至少您应该仍然能够捕获网络错误。 当MongoDB在groups of 1000中对批量插入操作进行分组时,此应该加快进程。

W 默认为1:

enter image description here

当您将其更改为0时:

enter image description here

如果您不关心元素的顺序,您可以获得一些调用无序批量操作的速度

await m_Collection.BulkWriteAsync(updates, new BulkWriteOptions() { IsOrdered = false });
  

使用无序操作列表,MongoDB可以并行执行   在列表中以任何顺序写入操作。 Link

答案 1 :(得分:0)

  

"数据库没有实质读取率,所以Sharding   不会改善问题,虽然也许我错了。"

更新涉及阅读。又发现被遗忘的_id - 所以如果不是有帮助的话,分片可能会有所帮助

答案 2 :(得分:0)

标记为答案很好。我想添加其他代码,以帮助使用InsertMany而非BulkWriteAsync的其他人更快地利用IsOrdered = false

    m_Collection.InsertMany(listOfDocument, new InsertManyOptions() { IsOrdered = false });

答案 3 :(得分:-4)

我们改用Cassandra因为Mongo不能很好地扩展。如果你说在80M之后你看到性能下降,很容易与内存有关。 我对SQL DB更专业,但我不会说25ms的非关键字段更新令人印象深刻。我怀疑类似的更新在Oracle,MySql上会表现得更好......