代码之家  ›  专栏  ›  技术社区  ›  Vasiliy Faronov

MongoDB完整集合扫描有多安全?

  •  0
  • Vasiliy Faronov  · 技术社区  · 6 年前

    假设我有一个很大的MongoDB集合。每天晚上,我都要对它运行一个查询,通过一个当前没有索引的字段进行过滤。我不在乎查询需要多长时间(我将监视它,如果开始需要超过几个小时,我将重新考虑)。因此,我不希望只为这个查询构建索引,因为每个索引都会带来一些操作开销。

    但是,我 需要注意的是,此完整扫描不会对MongoDB实例上的任何其他命令产生负面影响。它不能锁定任何东西,使我的磁盘I/O磨到停止,等等。

    如果这是一个单独的linux进程,我可以在 nice 和/或 ionice 是的。

    我/我是否需要在MongoDB中采取类似的预防措施?或者完全扫描在默认情况下通常是安全的?如果这取决于什么?

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

    2 回复  |  直到 6 年前
        1
  •  1
  •   kevinadi    6 年前

    这取决于以下因素的组合:

    • 你的磁盘速度 :由于集合扫描通常需要从磁盘(特别是在大集合上)执行大提取,因此更快的磁盘总体上更为有利。
    • WiredTiger缓存的大小和整个RAM的大小 :较大的内存大小通常允许您在内存中拥有更多的内容和更大的wiredtiger缓存,这对大多数工作负载都是有益的(不仅仅是在收集扫描上)。
    • 典型工作集的大小 :典型工作集越大,收集扫描工作完成后重新填充缓存所需的时间就越多。

    wiredtiger需要先将文档加载到其缓存中,然后才能对其进行操作或将其作为查询答复返回。这意味着执行集合扫描将用collscan集合替换缓存的内容。

    如果collscaned集合不构成典型的工作集,那么当需要集群执行工作时,它将需要再次从磁盘重新加载工作集。这可能会在缓存重新填充时显示为慢速查询,具体取决于磁盘满足请求的速度。

    换言之,集合扫描与典型工作集的比较将构成工作模式的更改,因此在工作负载更改期间应该会出现一些延迟。

    除此之外,wiredtiger是一个乐观的并发存储引擎,除了在全局元数据更改(drop collection、drop database等)期间,它不会真正锁定任何内容。它在发生冲突时透明地重试写操作,并且不会由于mvcc而阻塞读卡器。您所描述的工作应该受到磁盘性能的限制。

    注意 :上面描述的wiredtiger中的乐观并发性仅适用于副本集的主节点。在oplog应用期间读取第二个块,因为在oplog应用期间可能会出现数据库不一致的情况。

        2
  •  1
  •   Danziger    6 年前

    什么时候读二手书是个好主意?

    如果您不使用分片群集,但使用的是副本集,并且可以处理陈旧的数据,则可以 read from a secondary 以下内容:

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

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

    什么时候读二手书是个坏主意?

    From the docs 以下内容:

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

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

    https://jira.mongodb.org/browse/SERVER-5931 是的。

    不过,看来这个问题已经解决了 3.6 ,但我在 release notes 也不在 changelog 是的。

    如果您使用的是MongoDB 三点六 或者更高,你可能只是给这个解决方案一个尝试,否则你可以等待,看看是否有人可以在这个问题上有所启发。

    什么时候在二级数据库上建立索引是个好主意?

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