使用WiredTiger在4.2中将MongoDB功能测试设置和拆除速度降低10倍

马丁·梅尔卡(Martin Melka):

我正在将MongoDB从3.4(使用MMAPv1存储引擎)升级到4.2(使用WiredTiger)。在这一点上,我遇到的一个阻碍因素是测试速度严重下降。

长话短说(下面有更多详细信息)-MongoDB 4.2 WiredTiger需要花费更长的时间来处理测试中重复的数据库设置/拆卸。减速幅度约为10倍该测试过去通常运行约10分钟,而4.2则运行将近90分钟。即使仅进行了少量测试,此速度也会降低,并且似乎来自测试的设置/拆卸阶段。


环境

关于我们的环境的几句话-我们将PHP与Doctrine ODM结合使用来与MongoDB进行通信。我们实际上有使用数据库的大约3000个测试,一些纯单元测试,一些(许多)功能。这些测试在Docker化环境中运行-我们为每个管道启动了一个新的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()

函数文档说:

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

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

分析MongoDB

对PHP进行性能分析指出MongoDB的速度下降,因此我也对此进行了介绍。我运行的测试子集导致

  • 1366个针对3.4 MMAPv1的配置文件
  • 适用于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)的小型服务器上运行测试。对于测试可能创建的所有数据,绝对足够大它们确实是微不足道的,并且花费在它们上的大部分时间都在建立/拆卸数据库状态上。

结论

这是我第一次描述测试及其与数据库的交互。拖放创建与实际工作的比率可以肯定地得到改善,但是到目前为止,它已与MMAPv1和MongoDB 3.4一起使用。WiredTiger是否期望这种类型的减速?我有什么办法可以减轻这种情况?

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


编辑

使用 tmpfs

由于我正在Docker中运行测试,并且Docker支持tmpfs开箱即用的卷,因此我尝试了一下。当使用支持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个索引,这就是导致速度下降的原因。我没有找到直接从蒙戈的具体证据,但似乎索引创建与WiredTiger是显著比MMAPv1慢。从测试设置代码中删除索引创建可以大大加快测试速度,使我们回到升级前的时间。

我们的绝大多数测试不需要索引,并且其创建所需的时间比提供查询的速度要长得多。我实现了一个选项,以在开发人员知道他们将需要测试用例的情况下强制创建索引。这是我们可以接受的解决方案。

D.SM:

将数据库的数据放入内存。在Linux上,我建议使用zram

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

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在此示例中,为什么“严格使用”将性能提高了10倍?

WiredTiger MongoDB引擎排序:mongodb中的WiredTiger引擎的“自然排序”是否等同于“排序”?

使用WiredTiger扫描Mongodb整个索引,非常慢

在WiredTiger中对MongoDb文档执行部分更新是否比完整文档更新有任何优势?

使用Angular2和TypeScript将http功能移到其自己的服务中

在Angular 4中使用Bootstrap 4

在Angular 4中将全局设置保存到何处

将Bootstrap 4与Angular 4结合使用

WiredTiger和就地更新

MongoDB-WiredTiger快照与锁定

如何使用Jest和Enzyme测试React中的功能

使用React和Jest测试React中的组件功能

玩笑/酶单元测试:如何将存储传递给使用redux 4和react-redux 6连接功能的浅层组件

MongoDB WiredTiger是否使用聚簇索引?

由于src / mongo / db / storage / wiredtiger / wiredtiger_util.cpp 365上的致命断言28558,MongoDB Docker构建失败

Symfony 4中的功能测试事件和订阅者

为什么添加xorps指令使该功能使用cvtsi2ss并增加了约5倍的速度?

Docker-compose和mongoDB:无法在任何兼容版本下启动WiredTiger?

如何使用WiredTiger将MongoDB 2.6迁移到3.0

使用IN运算符的SQL查询停止查找索引并开始对其进行扫描,速度降低了100倍

使用wiredtiger和zlib压缩将csv文件导入MongoDB

MongoDB + WiredTiger +压缩-压缩是在客户端还是在服务器上完成?

$ inc就地编辑mongodb 3.2wiredtiger

MongoDB WiredTiger存储引擎cacheSizeGB配置选项

Angular 2-如何在使用Webpack的测试中将Scss与Bootstrap 4结合使用

Cassandra:设置 row_cache_size_in_mb 将性能降低 4 倍

使用 Enzyme 和 Jest 在 React 中测试处理更改功能

如何在swift 4中将html字符串设置为标签时使用常规和粗体字体设置自定义字体?

如何在 FastAPI 中的测试之间设置和拆除数据库?