Amazon DocumentDB 的最佳实践 - Amazon DocumentDB
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon DocumentDB 的最佳实践

了解使用 Amazon DocumentDB(与 MongoDB 兼容) 的最佳实践。随着新的最佳实践的确定,此节将不断更新。

基本操作指导方针

以下是使用 Amazon DocumentDB 时每个人都应遵循的基本操作指导方针。Amazon DocumentDB 服务等级协议要求您遵循以下指导方针。

  • 在两个 AWS 可用区中部署包含两个或更多 Amazon DocumentDB 实例的集群。对于生产工作负载,建议在三个可用区中部署包含三个或以上 Amazon DocumentDB 实例的集群。

  • 在规定的服务限制内使用服务。有关更多信息,请参阅Amazon DocumentDB 配额和限制

  • 监控您的内存、CPU、连接和存储使用情况。为帮助您维护系统性能和可用性,可将 Amazon CloudWatch 设置为在使用模式发生更改或接近部署容量时向您发送通知。

  • 当接近容量限制时,可以向上扩展您的实例。您应为这些实例预配置足够的计算资源(即 RAM、CPU),以满足无法预测的应用程序需求增长。

  • 设置您的备份保留期以与您的恢复点目标保持一致。

  • 测试您的集群的故障转移,以了解对于您的使用案例而言,该过程需要多长时间。有关更多信息,请参阅Amazon DocumentDB故障转移

  • 使用集群终端节点(请参阅Amazon DocumentDB 终端节点)以副本集模式(请参见 连接至 Amazon DocumentDB 作为副本集)连接到 Amazon DocumentDB 集群,以尽可能减少故障转移对应用程序的影响。

  • 选择一项驱动程序读取首选项设置,以便在满足应用程序的读取一致性要求的同时最大程度地提高读取扩展能力。secondaryPreferred 读取首选项将启用副本读取,并释放主实例以执行更多工作。有关更多信息,请参阅读取首选项选项

  • 将您的应用程序设计为在出现网络和数据库错误时能够灵活应对。使用您的驱动程序的错误机制来区分临时错误和持久性错误。适当时使用指数回退机制重试临时错误。确保您的应用程序在实施重试逻辑时考虑数据一致性。

  • 为所有生产集群或包含重要数据的任何集群启用集群删除保护。删除 Amazon DocumentDB 集群之前,请拍摄最终快照。如果要使用 AWS CloudFormation 部署资源,请启用终止保护。有关更多信息,请参阅终止保护和删除保护

  • 创建 Amazon DocumentDB 集群时,--engine-version 是默认为最新主引擎版本的可选参数。当前主引擎版本为 4.0.0。当新的主引擎版本发布时,--engine-version 的默认引擎版本将更新以反映最新的主引擎版本。因此,对于生产工作负载,特别是依赖于脚本、自动化或 AWS CloudFormation 模板的工作负载,我们建议您明确指定所需主要版本的 --engine-version。

调整实例大小

在 Amazon DocumentDB 中选择实例大小最重要的方面之一是缓存的 RAM 量。Amazon DocumentDB 为自己的服务保留三分之一的 RAM,这意味着仅三分之二的实例 RAM 可用于缓存。因此,Amazon DocumentDB 最佳实践是选择具有足够 RAM 的实例类型,以便在内存中容纳您的工作集(即数据和索引)。保证实例具有适当大小有助于优化整体性能,并可能最大限度地降低 I/O 成本。

要确定应用程序的工作集是否位于内存中,请使用 Amazon BufferCacheHitRatio 监控集群中每个有负载的实例的 CloudWatch。

BufferCacheHitRatio 指标用于衡量从实例的内存缓存(与存储卷)中提供的数据和索引的百分比。CloudWatch一般来说,BufferCacheHitRatio 的值应该尽可能高,因为从工作集内存读取数据比从存储卷读取数据更快、更具成本效益。虽然保证 BufferCacheHitRatio 尽可能接近 100% 是最理想的,但可实现的最佳值将取决于您的应用程序的访问模式和性能要求。为保证 BufferCacheHitRatio 尽可能高,建议为您集群中的实例配置足够 RAM,以便能够在内存中保存索引和工作数据集。

如果您的索引不在内存中,您将看到较低的 BufferCacheHitRatio。 从磁盘持续读取会产生额外的 I/O 成本,并且比从内存读取性能低。如果您的 BufferCacheHitRatio 比率低于预期,请上调集群的实例大小,以提供更多 RAM,以便将工作集数据容纳在内存中。如果上调实例类大小会导致 BufferCacheHitRatio 大幅提高,就表明应用程序的工作集不在内存中。继续向上扩展,直至 BufferCacheHitRatio 在扩展操作后不再大幅上升。有关监控实例的指标的信息,请参阅 Amazon DocumentDB 指标

根据您的工作负载和延迟要求,也许可以让您的应用程序在稳定状态使用期间具有较高 BufferCacheHitRatio 值,然后定期降低 BufferCacheHitRatio,因为分析实例需要扫描实例上运行的整个集合。定期降低 BufferCacheHitRatio 可能会很明显,因为后续查询需要将工作集数据从存储卷复制回缓冲区缓存,所以延迟时间较长。我们建议您首先在具有代表性生产工作负载的预生产环境中测试您的工作负载,以便了解性能特征和 BufferCacheHitRatio,然后再将工作负载部署到生产环境。

BufferCacheHitRatio 是特定于实例的指标,因此同一集群中不同实例可能具有不同的 BufferCacheHitRatio 值,具体取决于读取在主实例和副本实例之间的分配方式。如果运行工作负载无法处理因运行分析查询后重新填充工作集缓存而导致的定期延迟增加,应尝试将常规工作负载的缓冲缓存与分析查询的缓冲缓存隔离开。您可以通过将操作查询指向主实例,将分析查询指向仅指向副本实例,实现完全的 BufferCacheHitRatio 隔离。您还可以通过将分析查询定向到特定副本实例来实现部分隔离,但要知道有一定百分比的常规查询也将在该副本上运行,并且可能受到影响。

BufferCacheHitRatio 的值是否适当取决于您的使用案例和应用程序要求。此指标没有一个最佳值或最小值;只有您可以从成本和性能的角度决定是否可以接受 BufferCacheHitRatio 暂时较低的后果。

使用索引

建立索引

将数据导入 Amazon DocumentDB 时,最好在导入大型数据集之前先创建索引。您可以使用 Amazon DocumentDB 索引工具从正在运行的 MongoDB 实例或 mongodump 目录提取索引,然后在 Amazon DocumentDB 集群中创建这些索引。有关迁移的更多指导,请参阅迁移到 Amazon DocumentDB

索引选择性

我们建议您将索引创建限制为其中的重复值数量低于集合中总文档数的 1% 的字段。例如,如果您的集合包含 100,000 个文档,则仅在相同值出现 1000 次或更少的字段上创建索引。

选择具有大量唯一值(即高基数)的索引可确保筛选操作返回少量文档,从而在索引扫描期间产生良好的性能。高基数索引的一个例子是一个唯一索引,它保证相等谓词最多返回单个文档。低基数的示例包括布尔字段上的索引和一周中某天的索引。由于性能差,数据库的查询优化程序不太可能选择低基数索引。同时,低基数索引将继续消耗磁盘空间和 I/O 等资源。作为经验法则,应将索引定位于典型值频率为总集合大小的 1% 或更小的字段。

此外,建议仅在通常用作筛选条件的字段上创建索引,并定期查找未使用的索引。有关更多信息,请参阅如何识别未使用的索引?

索引对数据写入的影响

虽然索引可以通过避免扫描集合中的每个文档来提高查询性能,但这种提高是有代价的。对于集合的每个索引,每次插入、更新或删除文档时,数据库都必须更新集合并将字段写入集合的每个索引。例如,如果某个集合有九个索引,则数据库必须执行十次写入操作,才能将操作通知给客户端。因此,每增加一个索引就会增加一份写入延迟、I/O 开销和占用的总存储空间。

所以应该适当调整集群实例的大小,以确保将所有工作集容纳在内存中。这样可以避免持续从存储卷读取索引页,这会影响性能并产生更高的 I/O 开销。有关更多信息,请参阅调整实例大小

为了获得最佳性能,请尽量减少集合中的索引数量,仅添加必要的索引来提高常用查询的性能。虽然工作负载会变化,但有一个很好的指导原则,就是将每个集合的索引数量保持在五个以内。

识别缺失的索引

我们建议定期识别缺失的索引,这是一种最佳实践。有关详细信息,请参阅 如何识别缺失的索引?

识别未使用的索引

我们建议您定期识别并删除未使用的索引,这是一种很好的做法。有关详细信息,请参阅 如何识别未使用的索引?

安全最佳实践

出于安全考虑,您必须使用 AWS Identity and Access Management (IAM) 账户来控制对 Amazon DocumentDB API 操作的访问,尤其是创建、修改或删除 Amazon DocumentDB 资源的操作。此类资源包括集群、安全组和参数组。此外,您还必须使用 IAM 来控制执行常见管理任务的操作,例如备份和还原集群。创建 IAM 角色时,请采用最小权限原则。

成本优化

以下最佳实践可帮助您管理和最大程度地降低使用 Amazon DocumentDB 的成本。有关定价信息,请参阅 Amazon DocumentDB(与 MongoDB 兼容) 定价Amazon DocumentDB(与 MongoDB 兼容) FAQs

  • 在阈值为该月预期账单的 50% 和 75% 时创建账单提醒。有关创建账单提醒的更多信息,请参阅创建账单提醒

  • Amazon DocumentDB 的架构将存储与计算分离,因此即使是单实例集群也具备高持久性。集群存储卷在三个可用区中从六个方向复制数据,提供极高的持久性,而不论集群中有多少个实例。典型的生产集群具有三个或更多实例,以提供高可用性。但是,您在不需要高可用性时可使用单个实例开发集群,以优化成本。

  • 对于开发和测试场景,在不再需要时停止集群,并在恢复开发时启动集群。有关更多信息,请参阅停止和启动 Amazon DocumentDB 集群

  • 写入、读取和删除数据时,TTL 和更改流都会产生 I/O。如果您已启用这些功能,但未在应用程序中使用它们,则禁用这些功能有助于降低开销。

使用指标确定性能问题

要确定资源不足和其他常见瓶颈导致的性能问题,您可以监控可用于 Amazon DocumentDB 集群的指标。

查看性能指标

定期监控性能指标,以查看各种时间范围内的平均值、最大值和最小值。这可帮助您确定性能下降的时间。您还可以针对特定指标阈值设置 Amazon CloudWatch 警报,以便在达到这些阈值时向您发出警报。

要排除性能问题,了解系统的基准性能十分重要。设置新集群并让它在典型工作负载下运行之后,您应按一些不同的间隔(例如,1 小时、24 小时、1 周、2 周)来捕获所有性能指标的平均值、最大值和最小值。这将使您能够了解运行状况。这有助于将操作的峰值时间与非峰值时间进行比较。您随后可以利用这些信息确定性能何时降到标准水平以下。

您可以使用 AWS 管理控制台或 AWS CLI 查看性能指标。有关更多信息,请参阅下列内容:

设置 CloudWatch 警报

要设置 CloudWatch 警报,请参阅 中的Amazon CloudWatch使用 警报。Amazon CloudWatch 用户指南

评估性能指标

一个实例具有多个不同类别的指标。确定可接受的值的方式取决于指标。

CPU

  • CPU 利用率 — 使用的计算机处理容量的百分比。

Memory

  • 可用内存 — 实例上可用的 RAM 量。

  • 交换区使用情况 — 实例使用的交换空间量(以兆字节为单位)。

输入/输出操作

  • 读取 IOPS写入 IOPS — 每秒进行的磁盘读取或写入操作平均数。

  • 读取延迟写入延迟 — 读取或写入操作的平均时间(以毫秒为单位)。

  • 读取吞吐量写入吞吐量 — 每秒从磁盘读取或写入磁盘的平均兆字节数。

  • 磁盘队列深度 — 等待写入磁盘或从磁盘读取的 I/O 操作数。

网络流量

  • 网络接收吞吐量网络传输吞吐量 — 每秒出入实例的网络流量速率(以兆字节为单位)。

数据库连接

  • 数据库连接 — 连接到实例的客户端会话数。

一般而言,性能指标的可接受值取决于您的基准性能以及应用程序执行的操作。应调查相对于基准性能的一致或趋势性变化。

以下是有关特定类型的指标的建议:

  • 高 CPU 消耗 — CPU 消耗值高可能是正常情况,只要它们符合您的应用程序目标(如吞吐量或并发度)并且符合预期。如果 CPU 消耗始终高于 80%,请考虑扩展您的实例。

  • 高 RAM 消耗 — 如果 FreeableMemory 指标经常下降至总实例内存的三分之一以下,请考虑扩展您的实例。

  • 交换区使用情况 — 该指标应保持为零或接近零。如果交换区使用情况非常大,请考虑扩展您的实例。

  • 网络流量 — 对于网络流量,应与系统管理员讨论,以了解域网络和 Internet 连接的预期吞吐量。如果吞吐量始终低于预期,则应调查网络流量。

  • 数据库连接 — 如果发现用户连接数较高,同时实例性能下降并且响应时间延长,请考虑约束数据库连接。实例的最佳用户连接数因您的实例类所执行操作的复杂性而异。对于与性能指标有关的问题,提高性能的首要手段之一是优化最常使用和成本最高昂的查询,以了解这是否会减少对系统资源的压力。

如果优化查询后问题仍然存在,请考虑将您的 Amazon DocumentDB 实例类升级为具有更多与所遇问题相关的资源(CPU、RAM、磁盘空间、网络带宽,I/O 容量)的实例类。

优化查询

提高集群性能的最佳方式之一是优化最常使用和占用最多资源的查询,以降低其运行成本。

您可以使用分析器(请参阅 分析 Amazon DocumentDB 操作)来记录在您集群上执行的操作的执行时间和详细信息。对于监控集群上速度最慢的操作以帮助您提高单个查询的性能和整体集群性能,分析器非常有用。

您还可以使用 explain 命令来了解如何分析特定查询的查询计划。您可以使用此信息修改查询或底层集合以提高查询性能(例如,添加索引)。

TTL 和时间序列工作负载

TTL 索引到期后的文档删除是一个工作量巨大的过程。无法保证在任何特定时间段内删除文档。有大量因素会影响 TTL 进程删除过期文档的时间,包括实例大小、实例资源利用率、文档大小、总吞吐量、索引数量以及索引和工作集是否位于内存中,等等。

在 TTL 监视器删除文档时,每次删除都会产生 IO 开销,而这将增加您的账单费用。如果吞吐量和 TTL 删除速率增加,I/O 使用量也会随之增加,从而导致您的账单费用增加。但是,如果您没有创建 TTL 索引来删除文档,而是根据时间将文档分段到集合中,并在不再需要这些集合时直接删除它们,则不会产生任何 IO 成本。这可能会比使用 TTL 索引更具成本效益。

对于时间序列工作负载,您可以考虑创建滚动集合而不是 TTL 索引,因为滚动集合可以更高效地删除数据,同时 I/O 开销也更低。如果您有大型集合(特别是超过 1TB 的集合)或者比较关注 TTL 删除的 I/O 开销,我们建议您根据时间将文档划分成多个集合,并在不再需要集合中的文档时将集合删除。您可以每天或每周创建一个集合,具体取决于您的数据接收速率。虽然要求会因应用程序而异,但一个很好的经验法则是划分数量较多的小型集合,而不是数量较少的大型集合。删除这些集合不会产生 IO 开销,并且比使用 TTL 索引速度更快,成本效益更高。

Migrations

作为最佳做法,我们建议在将数据迁移到 Amazon DocumentDB 时,首先在 Amazon DocumentDB 中创建索引,然后再迁移数据。首先创建索引可以减少总时间并提高迁移速度。为此,您可以使用 Amazon DocumentDB 索引工具。有关迁移的更多信息,请参阅 Amazon DocumentDB 迁移指南

我们还建议您在迁移生产数据库之前,最好在 Amazon DocumentDB 上全面测试应用程序,并考虑功能、性能、操作和成本。

使用集群参数组

我们建议,在将集群参数组更改应用于生产集群前,您应在测试集群上试验这些更改。有关备份集群的信息,请参阅Amazon DocumentDB 中的备份和还原

聚合管道查询

创建具有多个阶段的聚合管道查询并且仅评估查询中的一个数据子集时,请将该 $match 阶段用作第一阶段或管道开头。首先使用 $match 将减少聚合管道查询中后续阶段需要处理的文档数量,从而提高查询性能。

batchInsertbatchUpdate

在执行较高比例的并发 batchInsert 和/或 batchUpdate 运算,而且主实例中 FreeableMemory 的数量(CloudWatch 指标)变为零时,您可以减少批量插入或更新工作负载的并发率,如果无法减少工作负载的并发率,也可以增大实例大小以减少 FreeableMemory 的数量。