MongoDB:随机读取与顺序读取性能

MongoDB:随机读取与顺序读取性能

我有一个单实例 mongodb,其中包含 3 个字段的集合:_id、block_id、payload。

  • 有效载荷始终是 4096 字节二进制文件
  • _id 是一个不断增加的唯一整数

该集合上有一个二级索引:

{ "v" : 1, "key" : { "block_id" : 1, "_id" : -1 }, 
  "ns" : "testdb.testdev", "name" : "_block_id_id" }

我正在进行许多查询,例如:

query: { query: { block_id: 868413 }, orderby: { _id: -1 } } ntoreturn:1 nscanned:1 nreturned:1 reslen:4166 163ms

在此期间没有其他查询。当我按 block_id 顺序读取时,它比使用随机 block_id 查询快 10 倍。我的 CPU 使用率很低,存储利用率也很低。集合比内存大小大 2-3 倍。

这里的瓶颈可能是什么?

答案1

这里有几件事需要澄清:

  1. 您只会看到默认记录的慢速查询(> 100 毫秒),您可能会有数百万个查询在该阈值下执行,但这些查询永远不会被记录
  2. 找出操作缓慢的原因的方法是查看记录缓慢操作时的统计数据
  3. 您应该使用以下方法重新运行查询。解释()确保他们正在使用你认为的索引

就统计数据而言,有两种基本方法可以获取它们。第一种也是最快的方法是蒙哥斯塔特蒙哥马利。这两个实用程序随 MongoDB 一起提供,可用于查明数据库正在做什么。

另一个选择是彩信(MongoDB 监控服务) - 它是免费的,它可以让您绘制随时间变化的所有相关统计数据,这样您就可以在看到速度缓慢时确定什么是峰值/下降。如果您选择这种方式,我建议您安装 munin-node(请参阅 MMS 文档),因为它可以让您查看 IO 统计数据以及 MongoDB 统计数据。

您通常会寻找下列内容之一:

  1. 页面错误 - 如果出现峰值,则您的查询会导致分页到磁盘 - 这比内存操作慢一个数量级,需要最小化。
  2. 常驻内存 - 与页面错误密切相关,这表示内存中的工作集。您提到您的数据集是 RAM 大小的 2-3 倍,但您是否在该估算中包含了索引(请参阅db.collection.stats()命令)

还有许多其他事情需要查看,但根据您的描述,这是一个很好的开始。请记住,如果您有内存争用,则越新的东西就越有可能已经在内存中。由于您使用的是顺序 ID,我预计较旧的 ID(除非最近更新或触及)会比新 ID 更频繁地出现在慢速查询日志中(这是操作系统通常管理内存的方式 - 请参阅最小可用单元了解更多信息)。

在解决此类性能问题方面,除了添加更多 RAM 之外,还应考虑:

  1. 删除可能占用空间的不需要的索引
  2. 看看使用涵盖指数如果可能的话进行查询(不需要分页数据,只需索引)
  3. 检查您的预读设置 - 这是一个漫长而复杂的话题 - 请参阅这里这里了解更多信息(以及更多信息)

相关内容