我们最近在 MongoDB 3.2 集群中遇到了与索引创建相关的破坏性事件。设想:
- 使用background: true在主数据库上创建了几个索引。
- 索引是在主数据库上完成后由 MongoDB 在辅助数据库上自动创建的,也是在后台创建的。
- 这最终导致多个后台索引操作在辅助节点上并行运行。到目前为止,一切都或多或少地按预期发生。
- 当 4 个索引器线程最终并行运行时,辅助节点上的所有读取操作似乎都阻塞了(编辑:澄清一下,这甚至包括对未构建索引的数据库的读取操作,根据文档,这甚至不应该发生用于前台构建)。我们使用 secondaryPreferred 选项执行一些读取,这些读取最终完全挂起(见下文)。
- 我们立即中止了进一步的索引创建以及仍在主服务器上运行的后台索引器线程。但是,在所有后台索引线程完成后,辅助节点上的读取操作才开始再次运行。总而言之,我们在 20 分钟内完全无法从二级读取。
什么可以解释这一点,特别是对辅助节点的读取操作最终完全阻塞的事实?索引创建会显着影响性能这一事实众所周知,我们正在考虑这一点。
但是,我们能够找到的文档中没有任何内容解释了在索引创建完成之前完全挂起的二级挂起。我们也无法在主要或次要的日志中发现任何可疑的内容:日志条目仅显示单个索引构建的创建和进度,但没有任何内容可以解释读取操作的阻塞。
这种情况给我们带来了一些重大问题,因为我们使用 Java 驱动程序的 ReadPreference.secondaryPreferred 选项执行某些读取。这些操作没有回退到从主服务器读取,而是在等待辅助服务器时没有超时地挂起,因此在我们的应用程序服务器上迅速建立了一个正在运行(但挂起)请求的大队列。
如果有人能对这种情况有所了解,我们将不胜感激。
技术细节:
- MongoDB 版本:3.2.16(不是最新的,但 .17/.18 更改日志中没有任何内容听起来可能会对此产生影响)
- 引擎:有线老虎
- 资源:主服务器虚拟机和辅助服务器虚拟机均配置有 6 个 CPU 和 128 GB 内存,两者之间有 1 GBit 链接。
- 数据集:约。总共 2 TB,其中约 100 GB 特别活跃。