1

Mongodb后台刷新阻塞所有请求:

服务器: Windows 服务器 2008 R2

CPU 使用率: 10%

内存: 64G,已使用 7%,Mongod 250MB

磁盘 % 读/写时间:小于 5%(根据 Perfmon)

MongoDB版本: 2.4.6

Mongostat 通常

insert:509 query:608 update:331 delete:*0 command:852|0 flushes:0 mapped:63.1g vsize:127g faults:6449 locked db:Radius:12.0%

Mongostat 之前(也许同时)冲洗

insert:1 query:4 update:3 delete:*0 command:7|0 flushes:0 mapped:63.1g vsize:127g faults:313 locked db:local:0.0%

Mongostat 冲洗后

insert:1572 query:1849 update:1028 delete:*0 command:2673|0 flushes:1 mapped:63.1g vsize:127g faults:21065 locked db:.:99.0%

正如您所看到的,当刷新发生锁定为 99% 时,此时 mongod 停止响应任何读/写操作(mongotop并且mongostat也停止)。刷新大约需要 7 到 8 秒才能完成,这不会使磁盘负载增加超过 10%。

有什么建议吗?

4

2 回答 2

3

在 Windows server 2008 R2(以及我怀疑的其他 Windows 版本,虽然我不确定)下,MongoDB 的(2.4 和更早版本)后台刷新进程强加一个全局锁,对读取和写入进行大量阻塞,并且长度刷新时间往往与 MongoDB 正在使用的内存量(内存映射文件的常驻和系统缓存)成正比,即使实际写入活动很少。这是我们在店里遇到的现象。

在我们使用 MongoDB 版本 2.2.2 的一个副本集中,在具有大约 128 GB RAM 的主机上,当大部分 RAM 用作常驻内存或备用系统缓存时,刷新时间可靠地在 10 到几乎没有负载下 15 秒,负载下可能高达 30 到 40 秒。这可能会导致 Mongo 每分钟都陷入长时间的无响应状态。我们的存储没有显示出压力的迹象。

看起来,基本问题是 Windows 处理对内存映射文件的刷新与 Linux 不同。显然,这个过程在 Windows 下是同步的,这有很多副作用,虽然我对技术细节的理解不够好,无法发表评论。

MongoDb, Inc. 已意识到此问题,并正在努力进行优化以解决此问题。该问题记录在两张票中:

https://jira.mongodb.org/browse/SERVER-13444

https://jira.mongodb.org/browse/SERVER-12401

该怎么办?

  1. 在某种程度上,这种现象与在低压力下测量的磁盘子系统的最小延迟有关,因此如果可以的话,您可以尝试使用更快的磁盘。据报道,这种方法有一些改进。
  2. 在一定程度上对我们有用的策略是避免配置过多的 RAM。碰巧我们真的不需要 128 GB 的 RAM,所以通过回拨 RAM,我们能够减少刷新时间。当然,这并不适合所有人。
  3. 最新版本的 MongoDB(2.6.0 及更高版本)似乎更好地处理了这种情况,因为在长时间刷新期间写入仍然被阻止,但读取能够继续进行。
  4. 如果您正在使用分片集群,您可以尝试通过在同一主机上放置多个分片来划分 RAM。我们自己没有尝试过,但似乎它可能有效。另一方面,强烈建议在任何此类场景中进行仔细的设计和测试,以避免影响性能和/或高可用性
  5. 我们尝试使用syncdelay。减少它并没有帮助(长冲洗时间只是更频繁地发生)。增加它有一点帮助(冲洗之间有更多时间来完成工作),但增加太多会严重加剧问题。我们曾一度将同步延迟提高到 5 分钟(300 秒),并获得了 20 分钟的背景刷新。
  6. MongoDB, Inc. 正在进行一些优化。这些可能很快就会推出。
  7. 在我们的案例中,为了减轻主要主机上的压力,我们定期重新启动其中一个辅助主机(清除所有内存),然后故障转移到它。自然,由于重新缓存,性能会受到一些影响,我认为这仅对我们有用,因为我们的工作量很大。而且,这种技术在任何意义上都不是解决方案。但是,如果高冲水时间造成严重破坏,这可能是一种“退烧”的方式。
  8. 考虑在 Linux 上运行... :-)
于 2014-07-26T22:44:55.833 回答
0

默认情况下,后台刷新不会阻止读/写。mongod 每 60 秒刷新一次,除非使用 -syncDelay 参数另外指定。syncDelay 使用 fsync() 操作,可以设置在内存页面刷新到磁盘时阻止写入。被阻止的写入也可能会阻止读取。阅读更多:http ://docs.mongodb.org/manual/reference/command/fsync/

但是,通常刷新不应超过 1000 毫秒(1 秒)。如果是这样,则可能是刷新到磁盘的数据量太大而您的磁盘无法处理。

解决方案:升级到更快的磁盘,如 SSD,或减少刷新间隔(尝试 30s,而不是默认的 60s)。

于 2014-07-25T18:11:32.237 回答