你有没有遇到MongoDB数据库的性能问题?运行查询时常见的情况是突然出现性能问题。明显的第一个解决方案是“让我们创建一个索引!” 虽然这在某些情况下有效,但在尝试优化MongoDB时还需要考虑其他选项。
性能不是一个拥有昂贵磁盘和千兆网络的大型机器的问题。事实上,这些并不一定是取得良好表现的关键。
MongoDB的性能来自良好的概念,组织和数据分布。我们将列出一些有关良好MongoDB优化的最佳实践。这不是一个详尽的或完整的指南,因为有很多变数。但这是一个好的开始。
1.保持文件简单
MongoDB是一个无模式数据库。这意味着默认情况下没有预定义的模式。我们可以在新版本中添加预定义的模式,但不是强制性的。了解使用嵌入式文档和数组时遇到的困难,因为在应用程序端/ ETL过程中解析数据会变得非常复杂。此外,数组可能会影响复制性能:对于数组中的每个更改,所有数组值都将被复制!
在MMAPv1中,选择正确的字段名称非常重要,因为数据库需要保存每个文档的字段名称。它不像在关系数据库中保存架构。让我们想象一下 ,如果您有一百万个文档,那么称为lastmessagefrom传感器的字段会占用多少数据:大约28 MB仅用于保存此字段名称!十个字段的集合需要280MB(仅用于保存一个空文档)。
几乎达到这种文件大小的文件是不可取的,因为数据库将需要大量页面来处理单个文件。这需要更多的CPU周期来完成任何操作。
2.硬件很重要,但...
使用好几个处理器和大量内存的硬件肯定有助于提高性能。
WiredTiger利用多个处理器来提供良好的性能。该存储引擎具有每文档锁定算法,因此可以同时运行尽可能多的处理器和尽可能多的操作(存在票据限制,但这超出了本文的范围)。但是,MMAPv1存储引擎必须锁定每个集合,有时不能利用多个处理器进行写入。
但是当一个实例死亡时,在三台大型机器(32个CPU,128个RAM和2TB磁盘)的环境中会发生什么?答案是它会进行故障转移 - 而且驱动程序足够聪明,可以读取运行状况实例并编写新的主要实例。但是,你的表现不一样。
情况并非总是如此,但在分布式环境中使用多台中小型机器可确保中断只会影响碎片的几个部分,而应用程序很少或根本没有感知。但是与此同时,更多的机器意味着很有可能失败。在设计环境时考虑这种折衷。正确的选择会影响性能。
3.阅读首选项和writeConcern
读取首选项和writeConcern根据公司的要求而有所不同。但请记住,新的MongoDB版本(3.6)使用writeConcern:“多数”和readConcern:“主要”。
这意味着它必须承认至少在所有写入((N / 0.5)+1)的写入,其中N是副本集中实例的数量。这可能会很慢。然而,这对于速度的一致性来说是一个公平的权衡。
请确保您使用的是最适合您的阅读偏好,并在您的公司中撰写关注。驱动程序始终从主服务器读取,但如果它不是您的环境要求,请考虑将查询分发到其他实例中。如果不这样做,这些实例仅用于故障转移,并且不会在常规操作中使用。
4.工作集
工作组有多大?通常,应用程序不会使用所有数据。一些数据经常更新,而其他数据则不是。
你的工作数据集是否适合RAM?当所有工作数据集在RAM中时都会发挥最佳性能。女性的迟缓,如页面错误,可能会影响性能,这取决于您使用的是什么。
读取(如备份,ETL或基本报告)可能会严重影响性能,因为存在竞争将页面放入缓存中的情况。大报告或汇总也是如此。
拥有多个用于多种用途的集合并将特定机器用于特定目的(如使用区域来保存不再使用的文档)将有助于实现简单和预期的工作集。