MongoDB-atlas-最佳实践-第2部分

蒙古数据库图谱从根本上简化了蒙古数据库的操作。 与任何托管数据库即服务一样,您仍然需要做出一些决定来确保应用程序的最佳性能和可用性。 这个博客系列(点击此处获取第1部分)提供了一系列建议,这些建议将作为充分利用蒙古数据库阿特拉斯服务的坚实基础。

像大多数数据库管理系统一样,索引是优化MongoDB查询性能的关键机制。 虽然索引会将某些操作的性能提高一个或多个数量级,但它们会增加更新、磁盘空间和内存使用的开销。 用户应该始终创建索引来支持查询,但不应该维护查询不使用的索引。 这对于支持大量插入(或修改索引值的写入)工作负载的部署尤为重要。

为了了解正在使用的现有索引的有效性,可以使用聚合阶段来确定每个索引的使用频率。 也可以通过MongoDB Compass访问这些信息。

蒙古数据库会自动优化查询,以尽可能高效地评估查询。 评估通常包括基于谓词的数据选择和基于所提供的排序标准的数据排序。 查询优化器通过定期运行备用查询计划并为每种查询类型选择性能最佳的索引来选择要使用的最佳索引。 这个经验测试的结果被存储为缓存的查询计划并定期更新。

MongoDB提供了一个计划功能,该功能显示了关于查询将如何或曾经如何被解决的信息,包括:

  • 返回的文档数。
  • 读取的文档数量。
  • 使用了哪些索引。
  • 查询是否被覆盖,这意味着不需要阅读任何文档来返回结果。
  • 是否执行了内存排序,这表明索引是有益的。
  • syncnavigator

  • 扫描的索引条目数。
  • 查询解析花费的时间(以毫秒为单位)(使用模式时)。
  • 哪些备选查询计划被拒绝(使用模式时)。

如果查询在1毫秒内得到解决,解释计划将显示0毫秒,这在良好调优的系统中是典型的。 当调用解释计划时,先前缓存的查询计划被放弃,并且重复测试多个索引的过程,以确保使用最佳可能的计划。 无需首先运行查询,就可以计算和返回查询计划。 这使数据库管理员能够查看哪个计划将用于执行查询,而不必等待查询运行完成。 来自的反馈将帮助您了解您的查询是否以最佳方式运行。

图1:蒙古数据库罗盘视觉解释计划

MongoDB Compass还提供了丰富的查询计划可视化,以帮助工程团队快速访问和优化查询执行。

MongoDB提供了一种称为数据库分析器的分析功能,它记录关于数据库操作的细粒度信息。 可以启用事件探查器来记录所有事件的信息,或者只记录持续时间超过可配置阈值(默认值为100毫秒)的事件的信息。 分析数据存储在一个有上限的集合中,可以很容易地在其中搜索相关事件。 查询此集合可能比解析日志文件更容易。

为所有文档创建属性的唯一索引。 如果在插入文档时没有指定值,MongoDB将自动创建该字段并分配一个唯一的值。 所有用户定义的索引都是辅助索引。 MongoDB支持多种类型的辅助索引,这些索引可以在文档中的任何字段上声明,包括数组和子文档中的字段。 索引选项包括:

  • 复合索引。
  • 地理空间索引。
  • 文本搜索索引。
  • 唯一索引。
  • 数组索引。
  • TTL索引。
  • 稀疏索引。
  • 部分索引。
  • 哈希索引。

您可以从《蒙古数据库体系结构指南》中了解关于这些索引的更多信息

索引和数据在MongoDB中同步更新,从而确保对索引的查询永远不会返回过时或删除的数据。 适当的索引应该作为模式设计过程的一部分来确定。 默认情况下,在MongoDB中创建索引是一个阻塞操作。 因为索引的创建可能是时间和资源密集型的,所以MongoDB提供了一个在复制集的主成员和次成员上创建新索引的选项,作为后台操作。 启用后台选项时,创建索引的总时间将比在前台创建索引的时间长,但在创建索引时仍可以查询数据库。

此外,可以在后台同时构建多个索引。 有关索引创建和持续维护的注意事项,请参考副本集上的构建索引文档。

以下提示可能有助于避免一些关于索引的常见错误:

  • 使用复合索引而不是索引交集: 为了在通过多个谓词进行查询时获得最佳性能,复合索引通常是更好的选择。
  • 复合索引:复合索引按字段定义和排序。 因此,如果为、和定义了复合索引,则指定或和的查询将能够使用该索引,但尝试基于进行搜索的查询将无法从该索引中受益。 删除作为其他索引前缀的索引。
  • 低选择性指数:索引应该从根本上减少可供选择的文档集。 例如,一个表明性别的字段的索引不如邮政编码的索引有用,甚至不如电话号码的索引有用。
  • 正则表达式:索引是按值排序的,因此前导通配符效率不高,可能会导致完全索引扫描。 如果表达式中有足够多的区分大小写的前导字符,尾随通配符可能是有效的。
  • 否认:就索引而言,不等式查询可能效率低下。 像大多数数据库系统一样,MongoDB不索引缺少值,否定条件可能需要扫描所有文档。 如果否定是唯一的条件,并且它不是选择性的(例如,查询订单表,其中99%的订单是完整的,以识别那些尚未完成的),所有记录都需要扫描。
  • 消除不必要的索引:索引是资源密集型的:即使它们消耗内存,并且随着字段的更新,也必须维护它们相关联的索引,从而导致额外的磁盘输入/输出开销。 为了了解正在使用的现有索引的有效性,可以使用聚合阶段来确定每个索引的使用频率。 如果存在未使用的索引,则删除它们将减少存储并加快写入速度。

蒙古数据库广泛使用内存来加速数据库操作。 在蒙古数据库中,所有数据都是通过内存中的数据表示来读取和操作的。 从内存读取数据以纳秒为单位,从磁盘读取数据以毫秒为单位,因此从内存读取比从磁盘读取快几个数量级。

在正常操作期间访问的数据和索引集称为工作集。 最佳做法是将工作集放入内存中。 工作集可能代表整个数据库的一小部分,例如在最常访问与最近事件或流行产品相关的数据的应用程序中。

当蒙古数据库试图访问尚未加载到内存中的数据时,必须从磁盘中读取。 如果有空闲内存,那么操作系统可以在磁盘上定位数据,并将其直接加载到内存中。 但是,如果没有空闲内存,MongoDB必须将一些其他数据从内存写入磁盘,然后将请求的数据读取到内存中。 这个过程可能很耗时,而且比访问已经驻留在内存中的数据要慢得多。

某些操作可能会无意中从内存中清除大部分工作集,从而对性能产生不利影响。 例如,当数据库大于服务器上的可用内存时,扫描数据库中所有文档的查询将导致文档被读入内存,并可能导致部分工作集被写入磁盘。 其他示例包括各种维护操作,如压缩或修复数据库以及重建索引。

如果您的数据库工作集大小超过了系统的可用内存,请考虑配置一个内存容量更大的实例(纵向扩展)或在其他实例之间分割数据库(横向扩展)。 扩展是一种自动化的在线操作,通过在单击 配置 按钮(图1)。 有关此主题的讨论,请参考博客系列第3部分中关于分享最佳实践的部分。 在系统资源被消耗之前更容易实现分片,因此容量规划是成功项目交付的一个重要因素。

图2:重新配置蒙古数据库图集集群

用户应该评估如何最好地为他们的应用程序建模他们的数据,而不是简单地导入他们遗留系统的平面文件导出。 在传统的关系数据库环境中,数据倾向于使用分隔的平面文件(如CSV)在系统之间移动。 虽然可以将数据从CSV文件摄取到蒙古数据库中,但这实际上可能只是数据迁移过程的第一步。 通常情况下,MongoDB的文档数据模型提供了关系数据模型中不存在的优势和选择。

有许多选项可以将数据从平面文件迁移到丰富的JSON文档中,包括自定义脚本、ETL工具以及应用程序本身,应用程序可以从现有的RDBMS中读取数据,然后将JSON版本的文档写回MongoDB。

其他工具,如和或蒙古数据库阿特拉斯备份,对于在不同的蒙古数据库系统之间移动数据非常有用。 将应用程序及其数据迁移到蒙古数据库地图集的使用和在“将数据迁移到蒙古数据库地图集”一文中进行了描述。

以下建议仅旨在为MongoDB部署的硬件提供高级指导。 硬件的具体配置将取决于您的数据、查询、性能服务级别协议和可用性要求。

与大多数数据库一样,当工作集(索引和最常访问的数据)适合内存时,蒙古数据库表现最好。 充足的内存是选择实例的最重要因素;如果内存不足,其他优化可能不会显著提高系统性能。 当选择使用哪个蒙古数据库阿特拉斯实例大小时,选择一个有足够内存来保存完整的工作数据集(或适当的子集,如果分片)。

如果您的工作集超过了可用内存,请考虑使用更大的实例类型或向您的系统添加额外的碎片。

使用更快的存储可以提高数据库性能和延迟一致性。 每个节点都必须配置足够的存储空间来存储整个数据集,或者将子集存储在单个碎片中。 在群集创建或重新配置过程中选择蒙古数据库阿特拉斯实例时,可以设置存储速度和大小。

图3:选择实例大小、存储大小和速度

可以选择对数据卷进行加密,以降低性能为代价来提高安全性。

蒙古数据库阿特拉斯实例是多线程的,可以利用许多中央处理器内核。 具体来说,活动线程的总数(即e.并发操作)会影响性能:

  • 随着并发活动操作的数量增加到超过CPU的数量,吞吐量也会增加。
  • 当并发活动操作的数量超过CPU数量一定阈值时,吞吐量最终会降低。

阈值金额取决于您的应用。 您可以通过实验和测量吞吐量来确定应用程序并发活动操作的最佳数量。

更大的蒙古数据库阿特拉斯实例包含更多的虚拟处理器,因此应该考虑高度并发的工作负载。

这是蒙古数据库阿特拉斯最佳实践博客系列的第2部分的总结。 在第3部分中,我们将深入研究扩展您的蒙古数据库阿特拉斯集群,并实现连续可用性。


如果你喜欢这篇文章,并想了解更多关于蒙古数据库的信息,请查看关于蒙古数据库的教程和文章。