MongoDB在后台刷新期间停止响应

时间:2013-11-03 15:59:10

标签: mongodb

Mongodb背景刷新会阻止所有请求:

服务器: Windows Server 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停止响应任何读/写操作(mongotopmongostat也停止)。冲洗大约需要7到8秒才能完成,这不会使磁盘负载增加10%以上。

有什么建议吗?

2 个答案:

答案 0 :(得分: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。减少它并没有帮助(长冲洗时间更频繁地发生)。增加它有点帮助(冲洗之间有更多的时间来完成工作),但增加太多会严重加剧这个问题。我们将syncdelay一度提升到五分钟(300秒),并获得了20分钟的背景冲洗。
  6. MongoDB,Inc。正在进行一些优化。这些可能很快就会推出。
  7. 在我们的情况下,为了减轻主要主机的压力,我们定期重新启动其中一个辅助设备(清除所有内存),然后故障转移到它。当然,由于重新缓存会导致一些性能损失,我认为这只对我们有用,因为我们的工作量很大。而且,这种技术在任何意义上都不是解决方案。但如果高冲洗时间导致严重的中断,这可能是减少发烧的一种方法。可以这么说。
  8. 考虑在Linux上运行......: - )

答案 1 :(得分:0)

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

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

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

相关问题