首页 > 解决方案 > MongoDB 全集合扫描的安全性如何?

问题描述

假设我有一个大型 MongoDB 集合。每天晚上,我都想对其进行查询,按当前未编制索引的字段进行过滤。我不在乎查询需要多长时间(我会监控它,如果它开始花费的时间超过几个小时,我会重新考虑)。所以我不想只为这个查询建立索引,因为每个索引都会带来一些操作开销。

然而,我真正关心的是这个完整扫描不会对这个 MongoDB 实例上的任何其他命令产生不利影响它不能锁定任何东西,让我的磁盘 I/O 停止,等等。

如果这是一个单独的 Linux 进程,我可能会在nice和/或ionice.

我可以/我需要在这里对 MongoDB 采取任何类似的预防措施吗?或者默认情况下完整扫描通常是安全的吗?如果“取决于”,取决于什么?

假设一个典型的 Linux 系统在典型的服务器硬件上运行。

标签: databasemongodbperformanceconcurrency

解决方案


什么时候从中学阅读是个好主意?

如果您没有使用分片集群,但您使用的是副本集并且您可以处理陈旧数据,您可以从辅助节点读取

db.collection.find({ ... }).readPref("secondary");

在运行分析/报告查询时这是一个好主意,因为它们通常是资源密集型和长时间运行的,因此如果这些在主服务器上运行,您将影响来自应用程序的读取和写入。

什么时候从中学阅读是个坏主意?

从文档

MongoDB 平衡器是一个后台进程,用于监控每个分片上的块数。当给定分片上的块数达到特定迁移阈值时,平衡器会尝试在分片之间自动迁移块并达到每个分片相同数量的块。

从分片集群上的辅助节点读取的问题是,当此进程正在运行或已中止时,您可能会得到重复、孤立、陈旧或丢失的数据。

请参阅https://jira.mongodb.org/browse/SERVER-5931

但是,看起来这已在 中修复,但我在发行说明更改日志3.6中都找不到任何提及此问题的内容。

如果您使用的是 MongoDB3.6或更高版本,则可以尝试此解决方案,否则您可以等待看看其他人是否可以对此有所了解。

什么时候在辅助节点上建立索引是个好主意?

您还可以考虑创建索引以加速单个辅助节点上的查询,不应该允许通过以下方式成为主节点:

  • 设置priority = 0, 使该节点不能成为主节点,否则您的应用程序的性能,尤其是写入性能,将由于更新此节点上的分析/报告索引的额外开销而急剧下降。

  • 使用隐藏节点,它可以防止与副本集的连接将读取路由到此特定节点,即使它们指定了读取首选项secondary

    但是,如果您使用的是 3 成员副本集,则拥有一个隐藏节点意味着如果另外 2 个节点出现故障,则第三个(隐藏的)节点将不会处理客户端读取。您可能会补偿这有 5 个成员(1 个隐藏)而不是 3 个。

  • 使用延迟节点,它也应该具有priority = 0并且被隐藏

  • 使用副本集标签集读取首选项将分析/报告查询路由到特定节点,这些节点将priority = 0隐藏但不会隐藏,因此它们可以从客户端读取。这也提供了一些其他方法所没有的额外灵活性。


推荐阅读