Mongo 大数据集的磁盘读取瓶颈和 IOPS 限制

Mongo disk read bottleneck for large data sets and IOPS limits

我无法理解与从 Mongo 数据库集合中的磁盘读取数据相关的瓶颈在哪里。我知道索引是优化查询的重要因素,但假设我们有一个没有索引的集合,我运行在一个有 2500 万条记录的集合中进行一个简单查询,大小约为 50Gb:

db.customers.find({ first_name: "xyz" })

当然,这得运行一个COLLSCAN,所以很慢(除非缓存在内存中)。但是 how 慢在我们的例子中很重要。 运行 一些测试表明,我 运行 此查询所用的机器没有与我的可用 IOPS 挂钩。在最大读取 IOPS ~10K 的机器上,这个简单的查询被限制在 1.2K 左右。注意 CPU iowait

查询显然受到磁盘的限制,但它没有充分利用计算机上可用的全部潜力。有趣的是,当我创建另一个数据库连接和 运行 两个异步查询时,IOPS 负载增加了 2 倍。似乎每个查询一次只能扫描磁盘上的这么多数据。 运行宁这些没有索引的查询时,是什么阻碍了它?

从长远来看,我认为将 Elasticsearch 引擎与其结合将有助于尝试对大量不同数据进行复杂搜索,但我真的很好奇为什么在这种情况下我们不能垂直扩展。

mongod节点使用类似于btree的结构来存储数据。叶页可以包含许多文档,最大 32Kb(压缩),或者单个文档,如果它的大小或更大。

集合扫描运行在存储引擎层之上的数据库层。数据库层在检查完当前文档后从存储中请求下一个文档。
如果文档已经在缓存中,存储层将 return 文档。如果没有,它将向操作系统请求下一页。 OS 可以从文件系统缓存中传送它或从磁盘中读取它。然后存储引擎解压,将文档存入缓存,将请求的文档提供给数据库层。

正在处理文档以查看它们是否与查询匹配的线程轮流使用存储引擎线程。当您 运行 同时进行 2 个查询时,会有第二个线程处理第二个查询,因此它们可以交错对磁盘的请求,从而导致更高的 IO 使用率。