【发布时间】:2011-11-30 01:38:42
【问题描述】:
在对 MongoDB 分片进行一些初步测试时,我希望并期望随着更多数据的加载,在一个分片/机器上执行仅命中单个数据块的查询的时间将保持相对恒定。但我发现速度明显放缓。
一些细节:
对于我的简单测试,我使用两台机器进行分片,并尝试对具有 200 万行和 700 万行的类似集合进行查询。这些显然是非常小的集合,甚至不需要分片,但我很惊讶已经看到查询只命中单个块的显着一致减速。查询包括分片键,用于从 10 到 100000 行的结果集,我测量了滚动整个结果集所需的总时间。另一件事:由于我的应用程序实际上需要的数据量远远超过 RAM 的容量,因此所有查询都是基于冷缓存进行计时的。
知道为什么会这样吗?有没有其他人观察到相同或矛盾的结果?
更多细节(由 Theo 提示):
对于这个测试,行很小(包括 _id 在内的 5 列),并且键不是基于 _id,而是基于几乎总是出现在查询中的多值文本列。
命令 db.printShardingStatus() 显示有多少块以及用于分割块范围的确切键值。该数据集的平均块包含超过 100,000 行,并且检查键值拆分可验证测试查询是否命中单个块。
出于本次测试的目的,我只测量了读数。没有插入或更新。
更新:
通过一些额外的研究,我相信我确定了减速的原因:MongoDB 块纯粹是逻辑的,并且它们中的数据在物理上并不是一起放置的(来源:Kristina Chodorow 的“Scaling MongoDB”)。这与 Oracle 和 MySQL 等传统数据库中的分区不同。这似乎是一个很大的限制,因为分片将随着分片/机器的添加而水平扩展,但在垂直维度上不太好,因为数据被添加到具有固定数量分片的集合中。
如果我正确理解这一点,如果我有 1 个集合,其中有 10 亿行分片在 10 个分片/机器上,那么即使只命中一个分片/机器的查询仍在从 1 亿行的大集合中进行查询。如果分片键的值恰好位于磁盘上,那可能没问题。但如果不是,并且我获取的行数超过几行(例如 1000 行),那么这似乎可能会导致大量 I/O 问题。
所以我的新问题是:为什么不在 MongoDB 中物理组织块以实现垂直和水平可扩展性?
【问题讨论】: