mongodb - MongoDB 中数十亿小文档的快速搜索策略

标签 mongodb search scalability pymongo database-performance

我需要存储数十亿个小型数据结构(每个数据结构大约 200 字节)。到目前为止,将每个元素存储为单独的文档运行良好,Mongo 每秒提供大约 10,000 个结果。我使用 20 字节哈希作为每个文档的 _id,并在 _id 字段上使用单个索引。在测试中,这适用于包含 5,000,000 个文档的数据集。

在操作中,我们每秒将发出大约 10,000 个请求,每秒更新现有文档大约 1,000 次,每秒插入新文档可能为 100 次或更少。

当我们无法在 RAM 中存储整个索引时,我们如何管理更大的数据集?如果我们将多个元素组合到每个文档中(以便更快地搜索索引,但每个查询中返回更多数据),MongoDB 的性能会更好吗?

与 SO 上的其他问题不同,我不仅对我们可以将多少数据填充到 Mongo 中感兴趣。它可以清楚地管理我们正在查看的数据量。我关心的是,在 RAM 有限的情况下,我们如何才能最大限度地提高大型集合上查找操作的速度。

我们的搜索往往是聚集的;大约 50,000 个元素将满足大约 50% 的查询,但其余 50% 将随机分布在所有数据中。我们能否通过将这 50% 的数据移入它们自己的集合中来获得性能提升,以便始终将最常用数据的较小索引保留在 RAM 中?

将 _id 字段的大小从 20 字节减少到 8 字节会对 MnogoDB 的索引速度产生重大影响吗?

最佳答案

我想到了一些策略:

1) 对“热门”文档使用不同的集合/数据库。

如果您知道哪些文档位于热集中,那么将它们移动到单独的集合中将会有所帮助。这将确保热文档共存于相同的范围/页面上。它还将使这些文档的索引更有可能完全在内存中。这是因为它更小并且(完全?)使用更频繁。

如果热门文档与其他文档随机混合,那么在加载文档时,您可能会在 B 树索引的更多叶元素中出现错误,因为另一个文档最近加载或访问该索引 block 的概率很小。

2) 缩短索引

索引值越短,适合单个 B 树 block 的值就越多。 (注意:键不包含在索引中。)单个存储桶中的条目越多,意味着存储桶越少,索引所需的总内存也越少。这意味着 block 保留在内存中的概率更高/生命周期更长。在您的示例中,减少 20->8 个字符比节省 50% 更好。如果您可以将这 8 个字节转换为 long,则可以节省更多,因为 long 没有长度前缀(4 个字节)和尾随 null(总共 5 个字节)。

3) 缩短键名。

字段名称越短,每个文档占用的空间就越少。 不幸的是,这会降低可读性。

4) 碎片

这实际上是在整个语料库的读取耗尽内存和最终磁盘带宽的情况下保持性能的唯一方法。如果您进行分片,您仍然需要对“热门”集合进行分片。

5) Adjust the read-ahead on disk to a small value.

由于“非热”读取是从磁盘加载随机文档,我们实际上只想将该文档及其周围尽可能少的文档读入/故障到内存中。一旦用户读取文件的一部分,大多数系统都会尝试预读一大块数据。这与我们想要的恰恰相反。

如果您发现系统故障较多,但 mongod 进程的驻留内存未接近系统可用内存,您可能会看到操作系统读取无用数据的影响。

6) 尝试对键使用单调递增的值。

这将触发优化(对于基于 ObjectId 的索引),当索引 block split 时,它将以 90/10 而不是 50/50 的比例进行优化。结果是索引中的大多数 block 将接近容量,您将需要更少的 block 。

如果您事后才知道“热门”50,000 个文档,那么按索引顺序将它们添加到单独的集合中也会触发此优化。

罗布。

关于mongodb - MongoDB 中数十亿小文档的快速搜索策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17752597/

相关文章:

php - 从用户代理检测机器人的最佳方法?

mysql全文搜索不首先返回最相关的结果

node.js - 如何在 node.js 和 mongoDB native 驱动程序上启用调试?

mongodb - 如何使用 Spring Data JPA 通过 Id 和设置为 "True"的 bool 值进行查询

node.js - Mongoose 从 `group` 之后的嵌套模式获取属性

java - 将 Java SE 应用程序作为服务与 Java EE 应用程序最佳实践集成

java - 静态方法是否有利于可扩展性?

java - 使用 Java 更新 Mongodb

javascript - 如何使用输入进行自动完成搜索?

mysql - MySQL数据库小型向中型过渡的解决方案