首页 > 科技周边 > IT业界 > 内存和磁盘性能如何影响您的MongoDB数据库

内存和磁盘性能如何影响您的MongoDB数据库

Jennifer Aniston
发布: 2025-02-16 09:56:12
原创
964 人浏览过

How Memory & Disk Performance Affects Your MongoDB Database

本文最初发表于MongoDB。感谢支持使SitePoint成为可能的合作伙伴。

理解各种内部缓存与磁盘性能之间的关系,以及这些关系如何影响数据库和应用程序性能,可能具有挑战性。我们使用了YCSB基准测试,改变工作集(测试中使用的文档数量)和磁盘性能,以更好地展示它们之间的关系。在审查结果时,我们将介绍一些MongoDB内部机制,以提高对常见数据库使用模式的理解。

关键要点

  1. 了解磁盘基线性能对于理解整体数据库性能至关重要。
  2. 高磁盘等待时间和利用率表明存在磁盘瓶颈。
  3. WiredTiger IO是随机的。
  4. 针对单个副本集的查询是单线程和顺序的。
  5. 磁盘性能和工作集大小密切相关。

摘要

整体系统性能的主要影响因素是工作集如何与存储引擎缓存大小(专用于存储数据的内存)和磁盘性能(它为访问数据的速度提供了物理限制)相关。

使用YCSB,我们探索了磁盘性能和缓存大小之间的相互作用,演示了这两个因素如何影响性能。虽然本测试使用了YCSB,但合成基准测试不能代表生产工作负载。通过这些方法获得的延迟和吞吐量数字不会映射到生产性能。我们使用了MongoDB 3.4.10、YCSB 0.14和MongoDB 3.6.0驱动程序进行这些测试。YCSB配置了16个线程和“uniform”只读工作负载。

我们证明,将工作集放入内存中可以提供最佳的应用程序性能,并且与任何数据库一样,超过此限制会对延迟和整体吞吐量产生负面影响。

理解磁盘指标

考虑磁盘性能时,有四个重要的指标:

  1. 磁盘吞吐量,或请求数乘以请求大小。这通常以每秒兆字节来衡量。4kb范围内的随机读写性能最能代表标准数据库工作负载。请注意,许多云提供商限制磁盘吞吐量或带宽。
  2. 磁盘延迟。在Linux上,这由await表示,即从应用程序发出读或写请求到数据被写入或返回到应用程序的时间(以毫秒为单位)。对于SSD,延迟通常低于3毫秒。HDD通常高于7毫秒。高延迟表示磁盘难以跟上给定的工作负载。
  3. 磁盘IOPS(每秒输入/输出操作)。iostat将此指标报告为tps。给定的云提供商可能会为给定的驱动器保证一定数量的IOPS。如果您达到此阈值,任何进一步的访问都将被排队,从而导致磁盘瓶颈。高端PCIe附加NVMe设备可以提供1,500,000 IOPS,而典型的硬盘可能只支持150 IOPS。
  4. 磁盘利用率。由iostat中的util报告。Linux每个设备有多个队列用于服务IO。利用率表示在给定时间内这些队列的百分比是多少。虽然这个数字可能令人困惑,但它是整体磁盘健康状况的一个良好指标。

测试磁盘性能

虽然云提供商可能会为给定的卷和磁盘提供IOPS阈值,并且磁盘制造商会发布预期的性能数字,但您系统上的实际结果可能会有所不同。如果观察到的磁盘性能有问题,执行IO测试会非常有帮助。

我们通常使用fio(灵活IO测试器)进行测试。我们在10GB的数据上进行了测试,ioengine为psync,读取范围在4kb到32kb之间。虽然默认的fio设置不能代表WiredTiger工作负载,但我们发现此配置是WiredTiger磁盘利用率的一个很好的近似值。

所有测试都在三种磁盘场景下重复进行:

场景1

AWS c5 io1 100GB卷提供的默认磁盘设置。5000 IOPS

  • 1144 IOPS / 5025 次物理读取/秒 / 99.85% 利用率

场景2

将磁盘限制为600 IOPS并引入7毫秒的延迟。这应该反映典型的带有硬盘的RAID10 SAN的性能

  • 134 IOPS / 150 次物理读取/秒 / 95.72% 利用率

场景3

进一步将磁盘限制为150 IOPS,延迟为7毫秒。这应该模拟普通旋转硬盘。

  • 34 IOPS / 150 次物理读取/秒 / 98.2% 利用率

查询如何从磁盘服务?

WiredTiger存储引擎执行自己的缓存。默认情况下,WiredTiger缓存的大小为系统内存的50%减去1GB,以便为其他系统进程、文件系统缓存和使用额外内存的内部MongoDB操作(例如构建索引、执行内存排序、重复数据删除结果、文本评分、连接处理和聚合)留出足够的空。为了防止缓存完全满导致性能下降,当利用率超过80%时,WiredTiger会自动开始从缓存中逐出数据。对于我们的测试,这意味着有效的缓存大小为(7634MB – 1024MB)* .5 * .8,或2644MB。

所有查询都由WiredTiger缓存服务。这意味着查询将导致索引和文档通过文件系统缓存读取到WiredTiger缓存中,然后再返回结果。如果请求的数据已在缓存中,则跳过此步骤。

WiredTiger默认使用snappy压缩算法存储文档。从文件系统缓存读取的任何数据在存储到WiredTiger缓存之前都会先解压缩。索引默认使用前缀压缩,并在磁盘和WiredTiger缓存中都被压缩。

文件系统缓存是操作系统结构,用于将经常访问的文件存储在内存中,以方便更快地访问。Linux在缓存文件方面非常积极,并将尝试使用文件系统缓存消耗所有可用内存。如果需要更多内存,则会逐出文件系统缓存,以便为应用程序提供更多内存。

这是一个动画图形,显示了由100个YCSB读取操作产生的YCSB集合的磁盘访问。每个操作都是单个文档的_id的单个查找。

左上角代表WiredTiger集合文件中的第一个字节。磁盘位置向右递增并环绕。每一行代表WiredTiger集合文件的3.5MB段。访问按时间顺序排列,并由动画帧表示。访问用红色和绿色方块表示,以突出显示当前的磁盘访问。

How Memory & Disk Performance Affects Your MongoDB Database

3.5 MB vs 4KB

在这里,我们看到我们的集合数据文件被读入内存。因为数据存储在B 树中,所以我们可能需要通过访问磁盘上的一个或多个位置来查找文档的磁盘位置(较小的访问),然后才能找到并读取我们的文档(较大的访问)。

这演示了MongoDB查询的典型访问模式——文档不太可能在磁盘上彼此靠近。这也表明,即使在彼此之后插入,文档也不太可能位于连续的磁盘位置。

WiredTiger存储引擎旨在“完全读取”:它将一次发出所有所需数据的读取请求。这导致我们建议将WiredTiger部署的磁盘提前读取限制为零,因为后续访问不太可能利用通过提前读取检索的额外数据。

工作集适合缓存

对于我们的第一组测试,我们将记录计数设置为200万,导致数据和索引的总大小为2.43 GB,或缓存的92%。

在这里,我们看到场景1的强大性能为每秒76,113个请求。检查文件系统缓存统计信息,我们观察到WiredTiger缓存命中率为100%,没有访问,并且没有字节读入文件系统缓存,这意味着在整个测试过程中不需要额外的IO。

不出所料,在场景2和场景3中,更改磁盘性能(添加7毫秒的延迟并将iops限制为600或150)对吞吐量的影响最小(分别为69,579.5和70,252次操作/秒)。

How Memory & Disk Performance Affects Your MongoDB Database

我们所有三个测试的99%响应延迟都在0.40到0.44毫秒之间。

工作集大于WiredTiger缓存,但仍适合文件系统缓存

现代操作系统缓存经常访问的文件以提高读取性能。因为文件已在内存中,所以访问缓存文件不会导致物理读取。free Linux命令显示的文件系统缓存统计信息详细说明了文件系统缓存的大小。

当我们将记录计数从200万增加到300万时,我们将数据和索引的总大小增加到3.66GB,比仅从WiredTiger缓存服务的大38%。

指标清楚地表明,我们平均读取548 mbps到WiredTiger缓存中,但是当检查文件系统缓存指标时,我们可以观察到99.9%的命中率。

对于此测试,我们开始看到性能下降,每秒仅执行66,720次操作,与我们的基线相比,减少了8%,而我们的基线仅从WiredTiger缓存服务。

正如预期的那样,在这种情况下,降低磁盘性能不会显着影响我们的整体吞吐量(分别为64,484和64,229次操作)。在文档更易于压缩或CPU是限制因素的情况下,从文件系统缓存读取的惩罚将更加明显。

How Memory & Disk Performance Affects Your MongoDB Database

我们注意到观察到的p99延迟增加了54%,达到.53–.55毫秒。

工作集略大于WiredTiger和文件系统缓存

我们已经确定WiredTiger和文件系统缓存协同工作以提供数据来服务我们的查询。但是,当我们将记录计数从300万增加到400万时,我们不能再仅仅利用这些缓存来服务查询。我们的数据大小增长到4.8GB,比我们的WiredTiger缓存大82%。

在这里,我们以257.4 mbps的速率读取到WiredTiger缓存中。我们的文件系统缓存命中率降低到93-96%,这意味着4-7%的读取导致从磁盘进行物理读取。

改变可用的IOPS和磁盘延迟对本测试的性能有巨大影响。

第99个百分位数的响应延迟进一步增加。场景1:19毫秒,场景2:171毫秒,场景3:770毫秒,与缓存内的情况相比,增加了43倍、389倍和1751倍。

与我们之前完全适合缓存的测试相比,当MongoDB提供完整的5000 iops时,我们看到性能降低了75%。场景2和场景3分别实现了5139.5和737.95次操作/秒,进一步证明了IO瓶颈。

How Memory & Disk Performance Affects Your MongoDB Database

工作集远大于WiredTiger和文件系统缓存

移动到500万条记录,我们将数据和索引大小增加到6.09GB,大于我们组合的WiredTiger和文件系统缓存。我们看到我们的吞吐量低于我们的IOPS。在这种情况下,我们仍然从文件系统缓存中服务81%的WiredTiger读取,但是从磁盘溢出的读取正在饱和我们的IO。我们看到此测试的文件系统缓存读取速度为71、8.3和1.9 Mbps。

第99个百分位数的响应延迟进一步增加。场景1:22毫秒,场景2:199毫秒,场景3:810毫秒,与缓存内响应延迟相比,增加了52倍、454倍和1841倍。在这里,更改磁盘IOPS会显着影响我们的吞吐量。

How Memory & Disk Performance Affects Your MongoDB Database

摘要

通过这一系列测试,我们证明了两个主要观点。

  1. 如果工作集适合缓存,磁盘性能不会很大程度上影响应用程序性能。
  2. 当工作集超过可用内存时,磁盘性能很快就会成为吞吐量的限制因素。

了解MongoDB如何利用内存和磁盘是调整部署规模和理解性能的重要组成部分。WiredTiger存储引擎的内部工作试图充分利用硬件,但内存和磁盘是影响工作负载整体性能特征的两个关键基础设施部分。

关于MongoDB中内存和磁盘性能的常见问题

MongoDB如何利用内存和磁盘空间?

MongoDB使用内存和磁盘空间来存储和管理数据。它使用内存映射文件系统进行数据存储,这意味着它将整个数据文件映射到RAM中。这允许MongoDB有效地处理大型数据集。操作系统的虚拟内存子系统管理细节,根据需要将数据进出内存交换。另一方面,磁盘空间用于存储数据文件、索引和日志。MongoDB自动以大块分配磁盘空间,以优化写入操作。

MongoDB中高磁盘I/O利用率的影响是什么?

高磁盘I/O利用率会严重影响MongoDB数据库的性能。它会导致读取和写入操作变慢,这会降低应用程序的整体性能。对于需要实时数据访问的应用程序来说,这尤其成问题。高磁盘I/O利用率还会导致CPU使用率增加,因为系统花费更多时间来管理磁盘操作。

如何监控MongoDB中的磁盘空间使用情况?

MongoDB提供了几种监控磁盘空间使用情况的工具。db.stats()命令提供数据库的高级概述,包括数据文件和索引的总大小。db.collection.stats()命令提供有关特定集合的更详细信息,包括数据和索引的大小。此外,MongoDB Atlas(MongoDB提供的数据库即服务产品)提供了一套全面的监控工具,包括有关高磁盘空间使用情况的警报。

如何解决MongoDB中的高磁盘空间利用率?

有几种策略可以解决MongoDB中的高磁盘空间利用率。一种方法是删除不必要的数据或集合。另一种方法是使用compact命令,该命令对数据文件进行碎片整理并回收未使用的磁盘空间。但是,此命令需要大量的可用磁盘空间,并且会影响数据库性能。分片(将数据分布到多台服务器)也可以帮助管理磁盘空间使用情况。

什么是RAM驱动器,它与MongoDB有什么关系?

RAM驱动器是操作系统视为磁盘驱动器的一块内存。因为RAM比磁盘存储快得多,所以使用RAM驱动器可以显着提高需要高速数据访问的应用程序的性能。但是,因为RAM是易失性的,所以当系统重新启动时,存储在RAM驱动器中的数据会丢失。在MongoDB的上下文中,RAM驱动器可用于存储经常访问的数据或索引以提高性能。但是,应谨慎执行此操作,因为如果系统重新启动,可能会发生数据丢失。

MongoDB如何处理内存管理?

MongoDB依赖于底层操作系统进行内存管理。它使用内存映射文件系统,允许操作系统的虚拟内存子系统管理内存中数据的细节以及磁盘上的数据。这种方法允许MongoDB有效地处理大型数据集,但这也意味着MongoDB的内存使用情况可能会受到同一系统上运行的其他进程的影响。

如何优化MongoDB的内存使用情况?

有几种策略可以优化MongoDB的内存使用情况。一种方法是确保您的工作集适合内存。工作集是经常访问的数据部分。如果您的工作集适合内存,MongoDB可以避免代价高昂的磁盘I/O操作。另一种方法是有效地使用索引。索引可以显着提高查询性能,但它们也会消耗内存。因此,明智地创建索引并监控它们对内存使用情况的影响非常重要。

MongoDB如何处理磁盘I/O操作?

MongoDB使用预写日志来确保数据完整性。在对数据文件进行任何更改之前,它们首先会被写入日志。这允许MongoDB从崩溃或电源故障中恢复。但是,日志记录也会增加磁盘I/O操作,这会影响性能。因此,监控磁盘I/O利用率并在必要时采取措施对其进行优化非常重要。

如何优化MongoDB的磁盘I/O操作?

有几种策略可以优化MongoDB的磁盘I/O操作。一种方法是使用SSD,它可以处理比传统硬盘更多的IOPS。另一种方法是使用针对写入操作进行优化的RAID配置。此外,您可以调整MongoDB的日志记录设置以减少对磁盘I/O的影响。但是,应谨慎执行此操作,因为它会影响数据完整性。

内存和磁盘性能如何影响MongoDB数据库的整体性能?

内存和磁盘性能是MongoDB数据库整体性能的关键因素。如果您的工作集适合内存,MongoDB可以避免代价高昂的磁盘I/O操作,这可以显着提高性能。同样,有效的磁盘I/O操作可以提高写入操作的性能并确保数据完整性。因此,监控和优化内存和磁盘性能以确保MongoDB数据库获得最佳性能非常重要。

以上是内存和磁盘性能如何影响您的MongoDB数据库的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板