Azure Cosmos DB Java SDK 的最佳做法

适用范围: NoSQL

本文演示使用 Azure Cosmos DB Java SDK 的最佳做法。 遵循这些做法将有助于改善延迟、提高可用性并提升整体性能。

清单

已选中 主题 详细信息/链接
SDK 版本 始终使用提供的最新版本 Azure Cosmos DB SDK,以便获取最佳性能。
单一实例客户端 在应用程序的生存期内使用 CosmosClient单个实例,以获得更好的性能
区域 确保在与 Azure Cosmos DB 帐户相同的 Azure 区域中运行应用程序,以尽可能减少延迟。 启用 2-4 个区域并在多个区域中复制帐户以获得最佳可用性。 对于生产工作负载,请启用服务托管故障转移。 如果没有此配置,则在写入区域服务中断的整个持续时间内,帐户将处于写入可用性缺失的状态,因为缺少区域连接时,手动故障转移将不会成功。 若要了解如何使用 Java SDK 来添加多个区域,请访问此处
可用性和故障转移 在 v4 SDK 中设置 preferredRegions。 在故障转移期间,系统会将写入操作发送到当前写入区域,并将所有读取操作发送到首选区域列表中的第一个区域。 有关区域故障转移机制的详细信息,请参阅可用性问题排查指南
CPU 由于客户端计算机上的资源不足,你可能会遇到连接/可用性问题。 监视运行 Azure Cosmos DB 客户端的节点上的 CPU 利用率,并在使用率非常高的情况下纵向/横向扩展。
Hosting 对于生产工作负载的最常见情况,强烈建议尽可能使用至少 4 核和 8 GB 内存的 VM。
连接模式 使用直接模式以获得最佳性能。 有关如何执行此操作的说明,请参阅 V4 SDK 文档
网络 如果使用虚拟机来运行应用程序,请在 VM 上启用加速网络,以帮助解决流量较大所致的瓶颈问题,并减少延迟或 CPU 抖动。 你可能还需要考虑使用最大 CPU 使用率低于 70% 的更高端虚拟机。
临时端口耗尽 对于稀疏或偶发性连接,建议将 idleEndpointTimeout 设置为较高的值。 DirectConnectionConfig 中的 idleEndpointTimeout 属性可帮助控制未使用连接的关闭时间。 这将减少未使用的连接数。 默认情况下,到终结点的空闲连接会保持打开状态 1 小时。 如果在空闲终结点超时持续时间内没有对特定终结点的请求,直接客户端将关闭到该终结点的所有连接以节省资源和 I/O 成本。
使用相应的计划程序(避免窃取事件循环 IO Netty 线程) 避免阻止调用:.block()。 为了受益于异步 API 模式并使用适当的线程处理和计划程序,整个调用堆栈都是异步的
端到端超时 若要获取端到端超时,请实施 Java SDK 中的端到端超时策略。 有关 Azure Cosmos DB 超时的更多详细信息,请访问此处
重试逻辑 暂时性错误是指根本原因很快就能自行解决的错误。 连接到你的数据库的应用程序应当构建为能预见这些暂时性错误。 为了处理这些错误,可在代码中实现重试逻辑,而不是将它们以应用程序错误的形式呈现给用户。 SDK 提供内置逻辑来处理可重试请求(如读取或查询操作)的这些暂时性故障。 由于写入操作不是幂等的,因此 SDK 不会针对暂时性故障重试写入。 SDK 允许用户为限制配置重试逻辑。 有关重试哪些错误的详细信息,请访问此处
缓存数据库/集合名称 从配置中检索数据库和容器的名称,或者一开始就将其缓存。 CosmosAsyncDatabase#read()CosmosAsyncContainer#read() 之类的调用将导致对服务的元数据调用,这些调用使用系统预留的 RU 限制。 还应该只使用一次 createDatabaseIfNotExists() 来设置数据库。 总体而言,不应频繁执行这些操作。
并行查询 Azure Cosmos DB SDK 支持并行运行查询,以便在查询时改善延迟和提高吞吐量。 建议将 CosmosQueryRequestsOptions 中的 maxDegreeOfParallelism 属性设置为你拥有的分区数。 如果不知道分区数,请将值设置为 -1,这将为你提供最佳延迟。 另外,将 maxBufferedItemCount 设置为预期返回的结果数,以限制预提取结果的数目。
性能测试回退 对应用程序执行测试时,应该按 RetryAfter 间隔实现回退。 允许退让有助于确保最大程度地减少等待重试的时间。
索引 Azure Cosmos DB 的索引策略还允许使用索引路径(IndexingPolicy#getIncludedPaths()IndexingPolicy#getExcludedPaths())指定要在索引中包括或排除的文档路径。 确保从索引中排除未使用的路径以加快写入速度。 有关如何使用 SDK 来创建索引的示例,请访问此处
文档大小 指定操作的请求费用与文档大小直接相关。 建议减小文档的大小,因为对大型文档执行操作比对小型文档执行操作成本更高。
Page Size 默认情况下,以包括 100 个项的块或 4 MB 大小的块返回查询结果(以先达到的限制为准)。 如果查询将返回超过 100 项,请增大页面大小以减少所需的往返次数。 内存消耗量将随着页面大小的增大而增大。
启用查询指标 有关后端查询执行的其他日志记录,请按照有关如何使用 Java SDK 捕获 SQL 查询指标的说明进行操作
SDK 日志记录 使用 SDK 日志记录来捕获其他诊断信息并排查延迟问题。 记录 Java SDK 中的 CosmosDiagnostics,以获取对服务的当前请求的更详细 Azure Cosmos DB 诊断信息。 对于示例用例,如果 CosmosDiagnostics#getDuration() 大于指定的阈值,则捕获任何异常和已完成操作的诊断(即,如果 SLA 为 10 秒,则在 getDuration()> 10 秒时捕获诊断)。 建议仅在性能测试期间使用这些诊断。 有关详细信息,请按照捕获 Java SDK 上的诊断中的说明操作
避免在标识符中使用任何特殊字符 某些字符受到限制,不能在某些标识符中使用:“/”、“\”、“?”、“#”。 一般建议不要在像数据库名称、集合名称、项 ID 或分区键这样的标识符中使用任何特殊字符,以避免任何意外行为。

使用网关模式时的最佳做法

使用网关模式时,Azure Cosmos DB 请求是通过 HTTPS/REST 发出的。 这些请求受制于每个主机名或 IP 地址的默认连接限制。 可能需要将 maxConnectionPoolSize 调整为其他值(从 100 到 1,000),以便客户端库能够同时使用多个连接来访问 Azure Cosmos DB。 在 Java v4 SDK 中,GatewayConnectionConfig#maxConnectionPoolSize 的默认值为 1000。 若要更改该值,可以将 GatewayConnectionConfig#maxConnectionPoolSize 设置为其他值。

具有大量写入操作的工作负载的最佳做法

对于具有大量创建有效负载的工作负荷,请将 CosmosClientBuilder#contentResponseOnWriteEnabled() 请求选项设置为 false。 该服务将不再将创建或更新的资源返回给 SDK。 通常,因为应用程序具有正在创建的对象,因此不需要服务即可将其返回。 标头值仍可访问,例如请求费用。 禁用内容响应有助于提高性能,因为 SDK 不再需要分配内存或序列化响应正文。 此外还会降低网络带宽的使用率,从而进一步提高性能。

后续步骤

若要详细了解 Java SDK 的性能提示,请参阅 Azure Cosmos DB Java SDK v4 的性能提示

若要深入了解如何设计应用程序以实现缩放和高性能,请参阅 Azure Cosmos DB 中的分区和缩放

尝试为迁移到 Azure Cosmos DB 进行容量计划? 可以使用有关现有数据库群集的信息进行容量规划。