你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

有关 Azure Cosmos DB Python SDK 的性能提示

适用范围: NoSQL

重要

本文中的性能提示仅适用于 Azure Cosmos DB Python SDK。 有关详细信息,请参阅 Azure Cosmos DB Python SDK 自述文件发行说明包 (PyPI)包 (Conda)故障排除指南

Azure Cosmos DB 是一个快速、弹性的分布式数据库,可以在提供延迟与吞吐量保证的情况下无缝缩放。 凭借 Azure Cosmos DB,无需对体系结构进行重大更改或编写复杂的代码即可缩放数据库。 扩展和缩减操作就像执行单个 API 调用或 SDK 方法调用一样简单。 但由于 Azure Cosmos DB 是通过网络调用访问的,因此在使用 Azure Cosmos DB Python SDK 时,可以通过客户端优化来实现最佳性能。

因此,如果询问“如何提高数据库性能?”,请考虑以下选项:

网络

  • 将客户端并置在同一 Azure 区域内以提高性能

如果可能,请将任何调用 Azure Cosmos DB 的应用程序放在与 Azure Cosmos DB 数据库所在的相同区域中。 通过大致的比较发现,在同一区域中对 Azure Cosmos DB 的调用可在 1-2 毫秒内完成,而美国西海岸和美国东海岸之间的延迟则 > 50 毫秒。 根据请求采用的路由,各项请求从客户端传递到 Azure 数据中心边界时的此类延迟可能有所不同。 通过确保在与预配 Azure Cosmos DB 终结点所在的同一 Azure 区域中调用应用程序,可能会实现最低的延迟。 有关可用区域的列表,请参阅 Azure Regions(Azure 区域)。

Azure Cosmos DB 连接策略图示。

与多区域 Azure Cosmos DB 帐户交互的应用需要配置首选位置,以确保请求进入并置区域。

启用加速网络以减少延迟和 CPU 抖动

建议按照说明在 Windows(选中以获取说明)Linux(选中以获取说明) Azure VM 中启用加速网络,以最大程度提高性能(减少延迟和 CPU 抖动)。

如果不使用加速网络,则在 Azure VM 与其他 Azure 资源之间传输的 IO 可能会不必要地通过位于 VM 与其网卡之间的主机和虚拟交换机进行路由。 在数据路径中以内联方式放置主机和虚拟交换机不仅会增加信道中的延迟和抖动,还会占用 VM 的 CPU 周期。 使用加速网络时,VM 直接与 NIC 连接,没有中介;以前由主机和虚拟交换机处理的任何网络策略细节现在都在 NIC 的硬件中处理;主机和虚拟交换机将被绕过。 通常情况下,当启用加速网络后,应会降低延迟并提高吞吐量,同时会提高延迟一致性并降低 CPU 利用率。

限制:加速网络必须受 VM OS 支持,并且只能在已停止并解除分配 VM 的情况下启用。 不能通过 Azure 资源管理器部署此 VM。 应用服务未启用加速网络。

有关更多详细信息,请参阅 WindowsLinux 说明。

SDK 用法

  • 安装最新的 SDK

Azure Cosmos DB SDK 正在不断改进以提供最佳性能。 请参阅 Azure Cosmos DB SDK 发行说明,以确定最新的 SDK 并查看改进内容。

  • 在应用程序生存期内使用单一实例 Azure Cosmos DB 客户端

每个 Azure Cosmos DB 客户端实例都是线程安全的,可执行高效的连接管理和地址缓存。 要通过 Azure Cosmos DB 客户端实现高效的连接管理和更好的性能,建议在应用程序生存期内使用单个 Azure Cosmos DB 实例。

  • 优化超时和重试配置

可以根据应用程序需求自定义超时配置和重试策略。 要获取可自定义的配置的完整列表,请参阅超时和重试配置文档。

  • 使用应用程序所需的最低一致性级别

创建 CosmosClient 时,如果在客户端创建中未指定任何内容,则使用帐户级别一致性。 有关一致性级别的详细信息,请参阅一致性级别文档。

  • 增大客户端工作负荷

如果以高吞吐量级别进行测试,客户端应用程序可能成为瓶颈,因为计算机的 CPU 或网络利用率将达到上限。 如果达到此上限,可以跨多个服务器横向扩展客户端应用程序以继续进一步推送 Azure Cosmos DB 帐户。

一个好的经验法则是,在任何给定的服务器上,CPU 利用率都不超过 50%,以保持较低的延迟。

  • OS 打开文件资源限制

某些 Linux 系统(例如 Red Hat)对打开的文件数和连接总数施加了上限。 运行以下命令以查看当前限制:

ulimit -a

打开的文件数 (nofile) 需要足够大,以便为配置的连接池大小和 OS 打开的其他文件留出足够的空间。 可以修改此参数,以增大连接池大小。

打开 limits.conf 文件:

vim /etc/security/limits.conf

添加/修改以下行:

* - nofile 100000

查询操作

有关查询操作,请参阅查询的性能提示

索引编制策略

  • 从索引中排除未使用的路径以加快写入速度

Azure Cosmos DB 的索引策略允许使用索引路径(setIncludedPaths 和 setExcludedPaths)指定要在索引中包括或排除的文档路径。 在事先知道查询模式的方案中,使用索引路径可改善写入性能并降低索引存储空间,因为索引成本与索引的唯一路径数目直接相关。 例如,以下代码演示如何使用“*”通配符从索引编制中纳入和排除文档的整个部分(也称为子树)。

container_id = "excluded_path_container"
indexing_policy = {
        "includedPaths" : [ {'path' : "/*"} ],
        "excludedPaths" : [ {'path' : "/non_indexed_content/*"} ]
        }
db.create_container(
    id=container_id,
    indexing_policy=indexing_policy,
    partition_key=PartitionKey(path="/pk"))

有关索引的详细信息,请参阅 Azure Cosmos DB 索引策略

吞吐量

  • 测量和优化较低的每秒请求单位使用量

Azure Cosmos DB 提供一组丰富的数据库操作,包括 UDF 的关系和层次查询、存储过程和触发 – 所有都在数据库集合的文档上操作。 与这些操作关联的成本取决于完成操作所需的 CPU、IO 和内存。 与考虑和管理硬件资源不同的是,可以考虑将请求单位 (RU) 作为所需资源的单个措施,以执行各种数据库操作和服务应用程序请求。

吞吐量是基于为每个容器设置的请求单位数量预配的。 请求单位消耗以每秒速率评估。 如果应用程序的速率超过了为其容器预配的请求单位速率,则会受到限制,直到该速率降到容器的预配级别以下。 如果应用程序需要较高级别的吞吐量,可以通过预配更多请求单位来增加吞吐量。

查询的复杂性会影响操作使用的请求单位数量。 谓词数、谓词性质、UDF 数目和源数据集的大小都会影响查询操作的成本。

若要测量任何操作(创建、更新或删除)的开销,请检查 x-ms-request-charge 标头来测量这些操作占用的请求单位数。

document_definition = {
    'id': 'document',
    'key': 'value',
    'pk': 'pk'
}
document = container.create_item(
    body=document_definition,
)
print("Request charge is : ", container.client_connection.last_response_headers['x-ms-request-charge'])

在此标头中返回的请求费用是预配吞吐量的一小部分。 例如,如果预配了 2000 RU/s,上述查询返回 1000 个 1KB 文档,则操作成本为 1000。 因此在一秒内,服务器在对后续请求进行速率限制之前,只接受两个此类请求。 有关详细信息,请参阅请求单位请求单位计算器

  • 处理速率限制/请求速率太大

客户端尝试超过帐户保留的吞吐量时,服务器的性能不会降低,并且不会使用超过保留级别的吞吐量容量。 服务器将抢先结束 RequestRateTooLarge(HTTP 状态代码 429)的请求并返回 x-ms-retry-after-ms 标头,该标头指示重新尝试请求前用户必须等待的时间量(以毫秒为单位)。

HTTP Status 429,
Status Line: RequestRateTooLarge
x-ms-retry-after-ms :100

SDK 全部都会隐式捕获此响应,并遵循服务器指定的 retry-after 标头,并重试请求。 除非多个客户端同时访问帐户,否则下次重试就会成功。

如果多个客户端一致地以高于请求速率的方式累积运行,则当前由客户端在内部设置为 9 的默认重试计数可能无法满足需要;在这种情况下,客户端会向应用程序引发状态代码为 429 的 CosmosHttpResponseError. 可以通过将 retry_total 配置传递给客户端来更改默认重试计数。 默认情况下,如果请求继续以高于请求速率的方式运行,则在 30 秒的累积等待时间后,将会返回 CosmosHttpResponseError 和状态代码 429。 即使当前的重试计数小于最大重试计数(默认值 9 或用户定义的值),也会发生这种情况。

尽管自动重试行为有助于改善大多数应用程序的复原能力和可用性,但是在执行性能基准测试时可能会造成冲突(尤其是在测量延迟时)。 如果实验达到服务器限制并导致客户端 SDK 静默重试,则客户端观测到的延迟会剧增。 若要避免性能实验期间出现延迟高峰,可以测量每个操作返回的费用,并确保请求以低于保留请求速率的方式运行。 有关详细信息,请参阅请求单位

  • 针对小型文档进行设计以提高吞吐量

给定操作的请求费用(请求处理成本)与文档大小直接相关。 大型文档的操作成本高于小型文档的操作成本。 最好在设计应用程序和工作流的架构时,将项大小设为大约 1KB 或类似的数量级。 对于延迟敏感型应用程序,应避免出现大项 - 大型文档会降低应用程序的速度。

后续步骤

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

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