繁体   English   中英

MongoDB删除速度非常慢

[英]MongoDB very slow deletes

我有一个三个mongod服务器的小副本集(每个16GB RAM,至少4个CPU核心和真正的硬盘驱动器)和一个专用仲裁器。 复制的数据目前有大约100,000,000条记录。 几乎所有这些数据都在一个集合中,其中包含_id (自动生成的Mongo ID)和date的索引,这是一个本地Mongo日期字段。 我会定期使用日期索引删除此集合中的旧记录,类似这样(来自mongo shell):

db.repo.remove({"date" : {"$lt" : new Date(1362096000000)}})

这确实有效,但运行速度非常慢。 我的一个节点的I / O比其他两个节点慢,只有一个SATA驱动器。 当此节点为主节点时,删除以约5-10个文档/秒运行。 通过使用rs.stepDown(),我降低了这个较慢的主要版本并强制选举以获得具有更好I / O的主要版本。 在那台服务器上,我得到大约100个docs / sec。

我的主要问题是,我应该担心吗? 在我介绍复制之前,我没有这些数字,但我知道删除速度要快得多。 我想知道副本集同步是否导致I / O等待,或者是否有其他原因。 在删除语句完成之前暂时禁用同步和索引更新我会非常满意,但我目前还不知道有什么方法可以做到这一点。 出于某种原因,当我禁用三个节点中的两个,只留下一个节点和仲裁器时,剩下的节点被降级并且写入是不可能的(不是仲裁者应该解决这个问题吗?)。

为了给出一般性能的一些指示,如果我删除并重新创建日期索引,则扫描所有100M文档大约需要15分钟。

这是因为即使如此

db.repo.remove({"date" : {"$lt" : new Date(1362096000000)}})

看起来像一个命令,它实际上在许多文档上运行 - 只要满足这个查询。

使用复制时,必须将每个更改操作写入local数据库中名为oplog.rs的特殊集合 - 简称oplog。

oplog必须为每个已删除的文档都有一个条目,并且每个条目中的每一个都需要应用于每个辅助节点上的oplog,然后才能删除相同的记录。

我可以建议您考虑的一件事是TTL索引 - 它们将根据您设置的到期日期/值“自动”删除文档 - 这样您就不会有一次大量删除,而是能够随着时间的推移更多地分散负载。

另一个可能不适合您的建议,但它对我来说是最佳解决方案:

  1. 从集合中删除indeces
  2. 迭代收集的所有条目并存储记录的id以删除到内存数组中
  3. 每次数组都足够大(对我而言是10K记录),我用ID去掉了这些记录
  4. 重建indeces

这是最快的方法,但它需要停止适合我的系统。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM