Mongodb 索引如何存储在磁盘上?

Joh*_*all 7 index mongodb

因此,让我首先从我对 MongoDb 如何将数据存储在磁盘上的理解开始这个问题:因此,当您在 mongodb 中创建数据库时,它会分配一个名为的大文件,<databasename>.0并在该文件中分配与特定数据对应的连续区域的范围集合或特定索引。

在填充此数据文件时,它会创建一个名为的新文件<databasename>.1并以类似方式填充它。因此,假设最近插入到特定数据库中的数据将位于编号最高的文件中似乎是明智的(我的性能测试证实了这一点)。

但是,我看不出这对索引来说是如何正确的……因为我们在谈论 bTree,所以让这个 bTree 以相同的方式分散在文件中似乎是不可能/明智的。由于 Mongo 正在对索引进行维护,整个索引是否存在于一个范围内,直到它超出它,然后将其重新定位到当前(编号最高的数据文件)?

这对我来说变得很重要,因为当从 Amazon EBS 快照启动数据库时,在卷预热之前访问这些数据文件似乎有巨大的开销。我只对集合中最近 N 个文档的一个子集感兴趣。如果我可以确定我只需要最近的几个数据文件,我可以在启动 mongod 之前通过顺序读取来预热这些文件。

Ada*_*m C 7

从快照加载时看到的延迟不是由索引在磁盘上的布局引起的,您看到延迟的可能性更大,因为当您从快照启动实例时,数据仅在第一次使用时加载,并且会比后续使用慢得多 - 这是以这种方式使用快照的基本限制,并且与尝试访问磁盘的应用程序几乎没有关系。这就是为什么你会看到“如何预热 EBS 卷”等指南(第一次写作也会受到惩罚)。如果您这样做(dd例如使用另一个应用程序预热磁盘)并且性能问题消失了,那么您就有相当不错的证据表明数据布局与该问题无关。

沿着这些路线,MongoDB 有touch 命令,它允许您在生气使用数据之前对其进行预热(您可以触摸数据、数据和索引或仅索引)。同样,在您最初连接音量后,它会很慢,并且触摸需要一段时间,但至少在热身阶段之后,您的结果应该有些一致。

就事物在磁盘上的存储方式而言,您在文件分配方面拥有正确的基础知识,但文件、范围内有一个逻辑结构,这是真正的存储单位。Mathias Stearn 是 MongoDB 的内核开发人员之一,在本次演讲中详细介绍了这一点以及更多内容。

索引只是 MongoDB 中另一种(结构化)数据形式,它们存储在整个文件的链接范围内。碎片可能会成为一个问题(这就是压缩命令的用途),磁盘空间使用(修复命令用于回收)也是如此,但是您没有描述会立即让我认为您遇到碎片问题的工作负载为什么我怀疑其他东西(比如第一次使用惩罚)是你的根本原因。