【问题标题】:MongoDB functional test setup and teardown 10x slower in 4.2 with WiredTigerMongoDB 功能测试设置和拆卸在 4.2 中使用 WiredTiger 慢 10 倍
【发布时间】:2020-07-16 17:17:22
【问题描述】:

我正在将我们的 MongoDB 从 3.4(使用 MMAPv1 存储引擎)升级到 4.2(使用 WiredTiger)。在这一点上,我遇到的一件几乎是阻碍的事情是我们的测试严重放缓。

长话短说(下面有更多详细信息)- MongoDB 4.2 WiredTiger 需要更长的时间来处理测试中重复的数据库设置/拆卸。 放缓幅度约为 10 倍。过去的测试运行大约 10 分钟,而 4.2 运行了将近 90 分钟。即使只进行了一小部分测试,这种减速也会重现,并且似乎来自测试的设置/拆卸阶段。


环境

简单介绍一下我们的环境——我们正在使用 PHP 和 Doctrine ODM 来与 MongoDB 对话。我们有大约 3000 个测试,一些纯单元测试,一些(很多)功能,实际使用数据库。测试在 Dockerized 环境中运行 - 我们为每个管道启动一个新的 MongoDB Docker 容器,但我已经确认即使在类似生产的裸机设置中也会出现同样的减速。下面的实验是在裸机上完成的,以限制来自其他地方的问题。

每个功能测试首先删除数据库,然后将夹具加载到其中(+ 创建索引),然后执行实际的测试场景。

分析 PHP

运行一小部分测试并测量时间,我得到以下结果:

3.4:
    real    0m12.478s
    user    0m7.054s
    sys     0m2.247s

4.2:
    real    0m56.669s
    user    0m7.488s
    sys     0m2.334s

如您所见,测试所用的实际 CPU 时间大致相同,没有显着差异。但实际时间非常不同,这表明需要大量等待(在这种情况下是等待 I/O?)。

我进一步分析了 PHP 代码,从结果中可以看出,在这个函数中花费的时间增加了 9-10 倍:

MongoDB\Driver\Manager::executeWriteCommand()

该函数的documentation 表示:

此方法将应用特定于写入命令的逻辑(例如 » drop)

这让我认为设置/拆卸的数量(即删除集合、创建索引)将在这里发挥作用。

分析 MongoDB

分析 PHP 指出了 MongoDB 的放缓,所以我也分析了这一点。我运行的测试子集导致

  • 3.4 MMAPv1 的 1366 个分析文档
  • 4.2 WiredTiger 的 2092 个分析文档

这些数字之间的大部分差异可归因于在 4.2 中没有createIndexes 的文档(也许它们被添加到 3.4 后的分析中?我不知道)。

我过滤了分析文档以仅显示那些花费至少 1 毫秒 (>0) 的文档。有:

  • 2 个这样的 MongoDB 3.4 文档(两个 drop 命令)
  • 950+ MongoDB 4.2 的此类文档(209x drop,715x createIndexes,4x insert,23x query

正如我之前提到的,Mongo 3.4 似乎没有在分析中报告createIndexes。但是让我们假设所有这些命令都将花费它们在 4.2 中的时间(不过,根据其余的分析结果,它们可能会花费更短的时间)。

然后是所有那些drop 命令,在 4.2 中每个操作最多需要 15 毫秒。在 3.4 中还有 209 个drop 命令,但据报道几乎所有命令都持续了 0 毫秒。

只有最少量的插入和查询,发生这些时集合的大小只有少数文档(每个集合少于 10 个,实际查询和插入的集合少于 5 个)。这种减速不是缺少缓存或索引的结果。在此设置下,即使是完整扫描也会很快。

内存和硬件

我发现的大部分讨论都是围绕为工作集设置适当的缓存大小。我在具有单核和 4GB RAM 的小型服务器上运行测试,默认缓存大小(应该是可用内存的 50%,即 2GB)。这对于 所有 测试可能创建的数据来说绝对足够大。它们真的很琐碎,大部分时间都花在了数据库状态的设置/拆卸上。

结论

这是我第一次分析我们的测试及其与数据库的交互。 drop-and-index-creation 与实际工作的比率肯定可以提高,但到目前为止它已在 MMAPv1 和 MongoDB 3.4 上工作。 WiredTiger 会出现这种类型的减速吗?有什么办法可以缓解这种情况吗?

我现在害怕升级生产 MongoDB 实例,因为我不知道它们的行为如何。如果这主要与索引创建和数据库删除有关,那么我认为生产工作负载应该没问题,但我不想冒险。遗憾的是,我们是一家相当小的公司,没有对生产环境进行任何性能/压力测试。


编辑

使用tmpfs

因为我在 Docker 和 Docker supports tmpfs volumes out-of-the-box 中运行测试,所以我试了一下。当使用 RAM 支持的 tmpfs 作为 MongoDB 数据的挂载时,我设法将测试时间缩短到一半左右:

4.2:
    real    0m56.669s
    user    0m7.488s
    sys     0m2.334s

4.2 - tmpfs:
    real    0m30.951s
    user    0m7.697s
    sys     0m2.279s

这更好,但与在 MMAPv1 上运行所需的 12 秒仍有很大差距。有趣的是,将 tmpfs 与 MMAPv1 结合使用并没有产生明显不同的结果。

测试放缓的真正原因 - 指数

事实证明,我们的测试框架和夹具加载器在每次数据库清除时为所有托管集合创建了索引。这导致每个测试用例创建了大约 100 个索引,这就是导致速度下降的原因。我没有直接从 Mongo 找到具体的证据,但似乎使用 WiredTiger 创建索引明显比使用 MMAPv1 慢。从测试设置代码中删除索引创建显着加快了测试速度,让我们回到了升级前的时间。

我们的绝大多数测试都不需要索引,而且它们的创建时间比它们提供的查询加速时间要长得多。我实现了一个选项来强制为开发人员知道他们需要它们的测试用例创建索引。这对我们来说是一个可以接受的解决方案。

【问题讨论】:

  • 在 3.4 和 4.0 之间有 很多 的变化。您可能需要分别测试各种操作,看看哪些操作变慢了,然后才开始调查原因。

标签: php mongodb doctrine doctrine-odm wiredtiger


【解决方案1】:

将数据库的数据放入内存。在 Linux 上,我推荐zram

根据我的经验,zram 在 raid 0 中的速度是顶级 nvme ssd(我认为是三星 860 pro)的 2 倍,并且我认为几乎是单个消费级笔记本电脑 SSD 的 10 倍。对于通过网络访问的旋转磁盘或存储,差异应该更大。

MongoDB 有各种其他存储引擎(我相信有一个称为“用于测试的临时”),但它们不支持事务,因此如果您的应用程序使用 4.2(甚至我认为是 4.0)功能,则需要使用 WT .

在生产中,您很可能不会在每个请求中都删除集合,因此 3.x 和 4.2 之间的实际性能差异应该更小。

【讨论】:

  • 感谢您的提示。将所有内容都放入 RAM 是一个吸引人的解决方案,但感觉就像是通过向其投入更多硬件来解决性能问题——它并没有解决性能下降的根本原因。确实,在生产环境中,我们并没有过多地丢弃集合,假设减速确实仅来自集合丢弃/设置而不是常规读/写,应该没问题。但在部署到生产环境之前,我想摆脱这个假设。不幸的是,您所指的 inMemory 存储引擎仅在 Enterprise 中可用:(
  • 我尝试使用 tmpfs 而不是 zram 纯粹是为了便于设置,我同意加速大约是 2 倍(在云设置中运行,因此可以安全地假设供应商会使用高端SSD)。
  • 我想您可以对特定操作进行基准测试,运行整个测试套件对于具体讨论不是很有用。
  • 您也可以在 4.0 中使用 mmap,您应该测试该组合与 3.4。
【解决方案2】:

使用ephemeralForTest引擎!

尽管@d-sm 在他们的回答中提到了这一点,但我错过了它,所以让我向未来的读者强调一下。

如果您只需要一个快速的存储引擎来运行您的单元测试,并且您需要将 MongoDB 更新到 v4.2+(所以 mmapv1 引擎不再是一个选项),您可以改用ephemeralForTest 引擎。 不要与仅限企业的 In-Memory 引擎混淆,它是在 v3.2 中默默添加的(请参阅 changelog)。

这个引擎在生产中没有得到官方支持并且有一些限制(例如缺乏事务支持),但它在单元测试的性能方面非常接近mmapv1(它也缺乏这些功能)。

所以也许它不适合所有用例,但我相信它对大多数人来说已经足够了,所以在尝试tmpfs 或其他解决方案之前先试一试,因为这些仍然不会授予相同的表演。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多