MongoDB - 重新启动服务器后不同的查询执行时间

标签 mongodb profiling

假设我启动了一个 mongo db 服务器:

mongo --dbpath=/some/path --port=12345 --storageEnginewiredTiger

然后我运行相同的查询 10 次(忽略第一个,以便它们都在热缓存上),如下所示:

mongo query1.js

我得到的时间是(通过 time 以及 mongodb 记录器验证):

8137ms 8145毫秒 8193毫秒 8091 毫秒 8152毫秒 8110毫秒 8182毫秒 8142毫秒 8133毫秒 8098 毫秒

太棒了——相当一致。所有这些都在大约 100 毫秒内,这是有道理的。

然后我以任何以下方式关闭服务器:

pkill mongod mongod --dbpath=/some/path --shutdown mongo shutdown.js

其中 shutdown.js 包含:

db.getSiblingDB('admin').shutdownServer();

然后我重新启动它,使用完全相同的命令,我得到以下时间:

8531ms 8492毫秒 8613毫秒 8555毫秒 8538ms 8512毫秒 8551毫秒 8511毫秒 8608ms 8522毫秒

同样,它们始终在约 100 毫秒内,但它们都处于不同的基线

如果我再次执行此操作,它可能在 8.38.68.9 或介于两者之间的任何位置。没有其他用户进程处于打开状态(除了那些需要 ssh 进入机器的用户进程)。

我做了如下实验:

当真时: 运行查询 25 次并记录最短的此类运行时间 关闭服务器并重新启动它,等待它监听

这个周末跑了两天,我没有和机器交互,收集了 223 个数据点,最小运行时间从 7.9s8.9s .如果我没有在两者之间关闭服务器,这不会发生,但同样,我可能会得到 7.9s 的基线,或者我可能会得到 8.9 的基线之一s

一个数据点的标准偏差(25 个查询的运行时间)总是非常低(大约 0.06),但在所有查询之间,却非常高。

是否有人对为什么会发生这种情况以及如何防止这种情况有直觉?我试图弄清楚一个查询是否比另一个查询快,但我无法获得一个好的基准来测试。重新启动服务器不是绝对必要的,但它会让我的生活更轻松,因为我并不总是让服务器运行。

最佳答案

MongoDB 使用缓存来为您提供一些查询服务。重新启动服务器时,必须清除一些缓存。 MongoDB 将所有最近使用的数据保存在 RAM 中。如果您为查询创建了索引并且您的工作数据集适合 RAM,则 MongoDB 从内存中提供所有查询。

查询计划保存在缓存中,在 mongo 重启时会清除。因此,第一次运行查询需要时间。请参阅说明(“执行统计”)。

通过 WiredTiger,MongoDB 使用文件系统缓存和 WiredTiger 缓存。默认情况下,从 MongoDB 3.2 开始,WiredTiger 缓存将使用 60% 的 RAM 减去 1 GB 或使用 1 GB,以较大者为准。对于具有高达 10 GB RAM 的系统,这小于或等于 3.0 设置。对于 RAM 超过 10 GB 的系统,配置大于 3.0 设置。

在 MongoDB 3.0 中,WiredTiger 缓存默认使用 1 GB 或已安装物理 RAM 的一半,以较大者为准。

MongoDB 还通过文件系统缓存自动使用机器上的所有空闲内存(文件系统缓存中的数据被压缩)。

查看 MongoDB Fundamentals

关于MongoDB - 重新启动服务器后不同的查询执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33742472/

相关文章:

java - MongoDB Java 驱动程序数组

具有 3 个子级别的 MongoDB 嵌套查找

node.js - Node.js 获取 mongoose 回调函数的返回值

c# - .net 内存测量和分析

ant - Apache Ant探查器

python - 我如何找出我的代码的哪些部分在 Python 中效率低下

mongodb - 是否可以将展开的数组的一个字段连接到展开的数组上?

mongodb - 如何在mongodb中找到两个日期之间的时差

c# - "sample"在探查器中代表多少秒?

ruby - 如何让 ruby​​-prof 忽略 Ruby 核心/标准库/gem 方法?