【问题标题】:Simple inserts and updates to MongoDB run very slowly under loadMongoDB 的简单插入和更新在负载下运行非常缓慢
【发布时间】:2016-01-12 03:13:46
【问题描述】:

我正在使用带有 2 个分片的集群的 Mongo 2.6.9,每个分片有 3 个副本,其中一个是隐藏的。 这是在 RedHat 上运行的 5 台机器部署,其中 4 台机器包含 1 个分片的单个副本,第 5 台机器包含两个分片的隐藏副本。 每秒运行大约 250 次插入和每秒 50 次更新的负载。这些是非常小的文档的简单插入和更新。 此外,还有一小部分插入到 GridFS 的小文件(大约 1 个文件/秒)。平均文件大小小于 1 MB。

为涉及的集合定义了 14 个索引。当我将添加将从数据库读取的应用程序时,这些将是必需的。

从我在整个运行过程中看到的主要副本的日志中,我看到大量简单的插入和更新,甚至是 GetLastError 请求,这些请求需要数百毫秒甚至有时几秒(默认日志记录级别仅显示耗时超过 100 毫秒的查询) )。例如,这个简单的更新使用索引进行查询并且不更新任何索引:

2015-10-12T06:12:17.258+0000 [conn166086] 更新 chatlogging.SESSIONS 查询:{ _id: "743_12101506113018605820fe43610c0a81eb9_IM" } 更新:{ $set: { EndTime: new Date(14446303351:nscannedObjects 6scan) :1 nMatched:1 nModified:1 keyUpdates:0 numYields:0 locks(micros) w:430 2131ms

2015-10-12T06:12:17.259+0000 [conn166086] command chatlogging.$cmd command: update { update: "SESSIONS", 更新: [ { q: { _id: "743_12101506113018605820fe43610c0a81eb9_IM" }, u: { $设置:{结束时间:新日期(1444630335126)}},多:假,upsert:假}],writeConcern:{w:1},有序:真,元数据:{shardName:“S1R”,shardVersion:[时间戳17000| 3、ObjectId('56017697ca848545f5f47bf5') ], session: 0 } } ntoreturn:1 keyUpdates:0 numYields:0 reslen:155 2132ms

所有插入和更新都是使用 w:1, j:1 进行的。

这些机器有大量可用的 CPU 和内存。磁盘 I/O 很重要,但在发生这些情况时不会接近 100%。

我真的需要弄清楚是什么导致了数据库的这种意外缓慢的响应速度。我很可能需要更改数据库的设置方式。 Mongo 使用默认配置运行,包括日志记录级别。

更新 -
我一直在研究这个问题,这里有一些额外的细节,我希望这些细节可以帮助找出问题的根本原因,或者至少为我指明正确的方向:

目前单个分片的总 DB 大小超过 200GB。索引几乎是 50GB。这是来自 db.stats() 的相关部分和来自 db.ServerStatus() 的 mem 部分,来自其中一个分片的主副本:

    "collections" : 7,
    "objects" : 73497326,
    "avgObjSize" : 1859.9700916465995,
    "dataSize" : 136702828176,
    "storageSize" : 151309253648,
    "numExtents" : 150,
    "indexes" : 14,
    "indexSize" : 46951096976,
    "fileSize" : 223163187200,
    "nsSizeMB" : 16,

“记忆”:{ “位”:64, “居民”:5155, “虚拟”:526027, “支持”:是的, “映射”:262129, “mappedWithJournal”:524258 },

服务器有 8GB 的​​ RAM,其中 mongod 进程使用大约 5GB。所以大部分数据和可能更重要的索引都没有保存在内存中。这会是我们的根本原因吗?当我之前写到系统有大量可用内存时,我指的是 mongod 进程没有尽可能多地使用它,而且大部分 RAM 用于缓存内存,如果需要可以释放这些内存:

free -m output

这是来自同一个 mongod 的 mongostat 的输出:

mongostat output

我确实发现这些故障很少,但这些数字对我来说太低了,无法表明存在真正的问题。我错了吗?

另外我不知道“locked db”中看到的数字是否被认为是合理的,或者这些数字是否表明我们有锁争用?

在获取这些统计信息的同一时间范围内,许多基于索引查找文档而不更新索引的简单更新操作,例如以下操作花费了数百毫秒:

2015-10-19T09:44:09.220+0000 [conn210844] 更新 chatlogging.SESSIONS 查询:{ _id:“838_19101509420840010420fe43620c0a81eb9_IM”} 更新:{ $set: { EndTime: new Date(1445247849092scannedObjects) :1 nMatched:1 nModified:1 keyUpdates:0 numYields:0 locks(micros) w:214 126ms

许多其他类型的插入或更新操作也需要数百毫秒。所以这个问题看起来是系统范围的,与特定类型的查询无关。使用 mtools 我无法找到扫描大量文档的操作。

我希望在这里我能够获得有关找到问题根本原因的帮助。我可以提供来自系统的任何其他信息或统计数据。

提前谢谢你,
狮子座

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    1) 首先您需要提高日志记录级别 2)使用mtools找出哪些查询很慢 3) 调整查询以找出您的瓶颈

    【讨论】:

    • 谢谢,我会尝试安装 mtools 看看能不能从那里学到更多。然而,关于找出慢查询,我已经知道那些来自 mongo 日志的查询。它显示了花费超过 100 毫秒的查询。在那里我看到了非常简单的查询,比如我附加的更新示例,它只需要太多时间。目前我无法弄清楚是什么导致它如此缓慢。
    • 您能否分享一下您的集合中存在哪些索引,因为如果每次插入更新多个索引,那么您的查询会更慢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多