适用于 Azure Cosmos DB 和 .NET 的性能提示Performance tips for Azure Cosmos DB and .NET

Azure Cosmos DB 是一个快速、弹性的分布式数据库,可以在提供有保证的延迟与吞吐量级别的情况下无缝缩放。Azure Cosmos DB is a fast, flexible distributed database that scales seamlessly with guaranteed latency and throughput levels. 凭借 Azure Cosmos DB,无需对体系结构进行重大更改或编写复杂的代码即可缩放数据库。You don't have to make major architecture changes or write complex code to scale your database with Azure Cosmos DB. 扩展和缩减操作就像执行单个 API 调用一样简单。Scaling up and down is as easy as making a single API call. 若要了解详细信息,请参阅预配容器吞吐量预配数据库吞吐量To learn more, see provision container throughput or provision database throughput.

因为 Azure Cosmos DB 是通过网络调用访问的,因此,使用 SQL .NET SDK 时可以通过进行客户端优化来获得最高性能。Because Azure Cosmos DB is accessed via network calls, you can make client-side optimizations to achieve peak performance when you use the SQL .NET SDK.

如果你尝试改善数据库性能,请考虑以下部分中提供的选项。If you're trying to improve your database performance, consider the options presented in the following sections.

托管方面的建议Hosting recommendations

对于查询密集型工作负载,请使用 Windows 64 位主机处理,而不要使用 Linux 或 Windows 32 位主机处理For query-intensive workloads, use Windows 64-bit instead of Linux or Windows 32-bit host processing

我们建议使用 Windows 64 位主机处理来改善性能。We recommend Windows 64-bit host processing for improved performance. SQL SDK 包含一个本机 ServiceInterop.dll,用于在本地分析和优化查询。The SQL SDK includes a native ServiceInterop.dll to parse and optimize queries locally. ServiceInterop.dll 仅在 Windows x64 平台上受支持。ServiceInterop.dll is supported only on the Windows x64 platform.

对于不支持 ServiceInterop.dll 的 Linux 和其他平台,将对网关发出附加的网络调用以获取优化的查询。For Linux and other unsupported platforms where ServiceInterop.dll isn't available, an additional network call is made to the gateway to get the optimized query.

此处列出的四个应用程序类型默认使用 32 位主机处理。The four application types listed here use 32-bit host processing by default. 若要将你的应用程序类型的主机处理更改为 64 位处理,请执行以下步骤:To change host processing to 64-bit processing for your application type, do the following:

  • 对于可执行应用程序:在“项目属性”窗口的“生成”窗格上,将平台目标设置为“x64”。For executable applications: In the Project Properties window, on the Build pane, set the platform target to x64.

  • 对于基于 VSTest 的测试项目:在 Visual Studio“测试”菜单上,选择“测试” > “测试设置”,然后将“默认处理器体系结构”设置为“X64”。 For VSTest-based test projects: On the Visual Studio Test menu, select Test > Test Settings, and then set Default Processor Architecture to X64.

  • 对于本地部署的 ASP.NET Web 应用程序:选择“工具” > “选项” > “项目和解决方案” > “Web 项目”,然后选择“为网站和项目使用 64 位版本的 IIS Express”。 For locally deployed ASP.NET web applications: Select Tools > Options > Projects and Solutions > Web Projects, and then select Use the 64-bit version of IIS Express for web sites and projects.

  • 对于在 Azure 上部署的 ASP.NET Web 应用程序:在 Azure 门户的“应用程序设置”中,选择“64 位”平台。For ASP.NET web applications deployed on Azure: In the Azure portal, in Application settings, select the 64-bit platform.

备注

新的 Visual Studio 项目默认设置为“任何 CPU”。By default, new Visual Studio projects are set to Any CPU. 我们建议将项目设置为“x64”,使其不会切换到“x86”。 We recommend that you set your project to x64 so it doesn't switch to x86. 如果添加了仅限 x86 的依赖项,则设置为“任何 CPU”的项目可以轻松切换到“x86”。 A project that's set to Any CPU can easily switch to x86 if an x86-only dependency is added.
ServiceInterop.dll 文件所处的文件夹必须是在其中执行 SDK DLL 的文件夹。The ServiceInterop.dll file needs to be in the folder that the SDK DLL is being executed from. 仅当你手动复制 DLL 或使用自定义的生成或部署系统时,这才是一个考虑因素。This should be a concern only if you manually copy DLLs or have custom build or deployment systems.

启用服务器端垃圾回收Turn on server-side garbage collection

在某些情况下,降低垃圾回收的频率可能会有帮助。Reducing the frequency of garbage collection can help in some cases. 在 .NET 中,将 gcServer 设置为 trueIn .NET, set gcServer to true.

横向扩展客户端工作负载Scale out your client workload

如果你在高吞吐量级别或速率大于 50,000 请求单位/秒(RU/秒)的情况下进行测试,则客户端应用程序可能会成为工作负荷瓶颈。If you're testing at high throughput levels, or at rates that are greater than 50,000 Request Units per second (RU/s), the client application could become a workload bottleneck. 这是因为计算机可能会达到 CPU 或网络利用率的上限。This is because the machine might cap out on CPU or network utilization. 如果达到此上限,可以跨多个服务器横向扩展客户端应用程序以继续进一步推送 Azure Cosmos DB 帐户。If you reach this point, you can continue to push the Azure Cosmos DB account further by scaling out your client applications across multiple servers.

备注

CPU 使用率高可能会导致延迟增大和请求超时异常。High CPU usage can cause increased latency and request timeout exceptions.

网络Networking

连接策略:使用直接连接模式Connection policy: Use direct connection mode

客户端连接到 Azure Cosmos DB 的方式对性能有重大影响,尤其是在观察到的客户端延迟方面。How a client connects to Azure Cosmos DB has important performance implications, especially for observed client-side latency. 有两个密钥配置设置可用于配置客户端连接策略:连接模式和连接协议。 Two key configuration settings are available for configuring client connection policy: the connection mode and the connection protocol. 两种可用的连接模式为:The two available connection modes are:

  • 直接模式(默认)Direct mode (default)

    直接模式支持通过 TCP 协议进行连接,在使用 Microsoft.Azure.Cosmos/.NET V3 SDK 的情况下是默认的连接模式。Direct mode supports connectivity through the TCP protocol and is the default connectivity mode if you're using the Microsoft.Azure.Cosmos/.NET V3 SDK. 与网关模式相比,直接模式提供的性能更佳且需要的网络跃点数更少。Direct mode offers better performance and requires fewer network hops than Gateway mode.

  • 网关模式Gateway mode

    如果应用程序在有严格防火墙限制的企业网络中运行,则网关模式是最佳选择,因为它使用标准 HTTPS 端口与单个终结点。If your application runs within a corporate network that has strict firewall restrictions, Gateway mode is the best choice, because it uses the standard HTTPS port and a single endpoint.

    但是,对于性能的影响是:每次在 Azure Cosmos DB 中读取或写入数据时,网关模式都涉及到额外的网络跃点。The performance tradeoff, however, is that Gateway mode involves an additional network hop every time data is read from or written to Azure Cosmos DB. 因此,直接模式因为网络跃点较少,可以提供更好的性能。So Direct mode offers better performance because there are fewer network hops. 在套接字连接数量有限的环境中运行应用程序时,我们也建议使用网关连接模式。We also recommend Gateway connection mode when you run applications in environments that have a limited number of socket connections.

    在 Azure Functions 中使用 SDK 时,尤其是在消耗计划中使用时,请注意当前的连接限制When you use the SDK in Azure Functions, particularly in the Consumption plan, be aware of the current limits on connections. 这种情况下,如果还在 Azure Functions 应用程序中使用其他基于 HTTP 的客户端,则使用网关模式可能更好。In that case, Gateway mode might be better if you're also working with other HTTP-based clients within your Azure Functions application.

在直接模式下使用 TCP 协议时,除了网关端口外,还需确保从 10000 到 20000 这个范围内的端口处于打开状态,因为 Azure Cosmos DB 使用动态 TCP 端口。When you use the TCP protocol in Direct mode, in addition to the gateway ports, you need to ensure that the port range from 10000 through 20000 is open, because Azure Cosmos DB uses dynamic TCP ports. 专用终结点上使用直接模式时,应打开从 0 到 65535 的整个 TCP 端口范围。When you use Direct mode on private endpoints, the full range of TCP ports from 0 through 65535 should be open. 默认情况下,标准 Azure VM 配置的端口是打开的。The ports are open by default for the standard Azure VM configuration. 如果这些端口未处于打开状态,你在尝试使用 TCP 时将收到“503 服务不可用”错误。If these ports aren't open and you try to use TCP, you'll receive a "503 Service Unavailable" error.

下表显示了可用于各种 API 的连接模式,以及用于每个 API 的服务端口:The following table shows the connectivity modes that are available for various APIs and the service ports that are used for each API:

连接模式Connection mode 支持的协议Supported protocol 支持的 SDKSupported SDKs API/服务端口API/Service port
网关Gateway HTTPSHTTPS 所有 SDKAll SDKs SQL (443)、MongoDB(10250、10255、10256)、表 (443)、Cassandra (10350)、Graph (443)SQL (443), MongoDB (10250, 10255, 10256), Table (443), Cassandra (10350), Graph (443)

端口 10250 映射到没有异地复制功能的默认 Azure Cosmos DB API for MongoDB 实例,端口 10255 和 10256 映射到具有异地复制功能的实例。Port 10250 maps to a default Azure Cosmos DB API for MongoDB instance without geo-replication, and ports 10255 and 10256 map to the instance with geo-replication.
直接Direct TCPTCP .NET SDK.NET SDK 使用公共/服务终结点时:端口介于 10000 到 20000 之间When you use public/service endpoints: ports in the 10000 through 20000 range

使用专用终结点时:端口介于 0 到 65535 之间When you use private endpoints: ports in the 0 through 65535 range

Azure Cosmos DB 提供基于 HTTPS 的简单开放 RESTful 编程模型。Azure Cosmos DB offers a simple, open RESTful programming model over HTTPS. 此外,它提供高效的 TCP 协议,该协议在其通信模型中也是 RESTful,可通过 .NET 客户端 SDK 获得。Additionally, it offers an efficient TCP protocol, which is also RESTful in its communication model and is available through the .NET client SDK. TCP 协议使用传输层安全性 (TLS) 来进行初始身份验证和加密通信。The TCP protocol uses Transport Layer Security (TLS) for initial authentication and encrypting traffic. 为了获得最佳性能,请尽可能使用 TCP 协议。For best performance, use the TCP protocol when possible.

对于 SDK V3,可以在 CosmosClientOptions 中创建 CosmosClient 实例时配置连接模式。For SDK V3, you configure the connection mode when you create the CosmosClient instance in CosmosClientOptions. 请记住,直接模式是默认设置。Remember that Direct mode is the default.

string connectionString = "<your-account-connection-string>";
CosmosClient client = new CosmosClient(connectionString,
new CosmosClientOptions
{
    ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
});

由于仅在直接模式下才支持 TCP,如果使用网关模式,则 HTTPS 协议始终用来与网关通信。Because TCP is supported only in Direct mode, if you use Gateway mode, the HTTPS protocol is always used to communicate with the gateway.

使用不同的连接模式和协议建立到 Azure Cosmos DB 的连接。

临时端口耗尽Ephemeral port exhaustion

如果实例上的连接量较高或端口使用率较高,请先确认客户端实例是否为单一实例。If you see a high connection volume or high port usage on your instances, first verify that your client instances are singletons. 换句话说,客户端实例在应用程序生存期内应是唯一的。In other words, the client instances should be unique for the lifetime of the application.

在 TCP 协议上运行时,客户端使用长生存期连接来优化延迟。When it's running on the TCP protocol, the client optimizes for latency by using the long-lived connections. 这与 HTTPS 协议相反,后者在处于非活动状态两分钟后终止连接。This is in contrast with the HTTPS protocol, which terminates the connections after two minutes of inactivity.

在具有稀疏访问且与网关模式访问相比连接计数更高的情况下,你可以:In scenarios where you have sparse access, and if you notice a higher connection count when compared to Gateway mode access, you can:

  • CosmosClientOptions.PortReuseMode 属性配置为 PrivatePortPool(Framework 版本 >= 4.6.1 且 .NET Core 版本 >= 2.0 时有效)。Configure the CosmosClientOptions.PortReuseMode property to PrivatePortPool (effective with framework versions 4.6.1 and later and .NET Core versions 2.0 and later). 此属性使 SDK 可以针对各种 Azure Cosmos DB 目标终结点使用一小部分临时端口。This property allows the SDK to use a small pool of ephemeral ports for various Azure Cosmos DB destination endpoints.
  • CosmosClientOptions.IdleConnectionTimeout 属性配置为大于或等于 10 分钟。Configure the CosmosClientOptions.IdleConnectionTimeout property as greater than or equal to 10 minutes. 建议值为 20 分钟到 24 小时。The recommended values are from 20 minutes to 24 hours.

出于性能考虑,请将客户端并置在同一 Azure 区域中For performance, collocate clients in the same Azure region

如果可能,请将任何调用 Azure Cosmos DB 的应用程序放在 Azure Cosmos DB 数据库所在的区域。When possible, place any applications that call Azure Cosmos DB in the same region as the Azure Cosmos DB database. 通过大致的比较发现:在同一区域中对 Azure Cosmos DB 的调用可在 1-2 毫秒内完成,而美国西海岸和美国东海岸之间的延迟则大于 50 毫秒。Here's an approximate comparison: calls to Azure Cosmos DB within the same region finish within 1 millisecond (ms) to 2 ms, but the latency between the West and East coast of the US is more than 50 ms. 根据请求采用的路由,各项请求从客户端传递到 Azure 数据中心边界时的此类延迟可能有所不同。This latency can vary from request to request, depending on the route taken by the request as it passes from the client to the Azure datacenter boundary.

确保调用应用程序位于预配的 Azure Cosmos DB 终结点所在的 Azure 区域即可尽可能降低延迟。You can get the lowest possible latency by ensuring that the calling application is located within the same Azure region as the provisioned Azure Cosmos DB endpoint. 有关可用区域的列表,请参阅 Azure 区域For a list of available regions, see Azure regions.

使用不同的连接模式和协议建立到 Azure Cosmos DB 的连接。

增加线程/任务数目Increase the number of threads/tasks

由于对 Azure Cosmos DB 的调用是通过网络执行的,可能需要改变请求的并发度,以便最大程度地减少客户端应用程序等待请求的时间。Because calls to Azure Cosmos DB are made over the network, you might need to vary the degree of concurrency of your requests so that the client application spends minimal time waiting between requests. 例如,如果使用 .NET 任务并行库,请创建大约数百个在 Azure Cosmos DB 中进行读取或写入操作的任务。For example, if you're using the .NET Task Parallel Library, create on the order of hundreds of tasks that read from or write to Azure Cosmos DB.

启用加速网络Enable accelerated networking

为了降低延迟和 CPU 抖动情况,建议在客户端虚拟机上启用加速网络。To reduce latency and CPU jitter, we recommend that you enable accelerated networking on your client virtual machines. 有关详细信息,请参阅创建具有加速网络的 Windows 虚拟机创建具有加速网络的 Linux 虚拟机For more information, see Create a Windows virtual machine with accelerated networking or Create a Linux virtual machine with accelerated networking.

SDK 用法SDK usage

安装最新的 SDKInstall the most recent SDK

Azure Cosmos DB SDK 正在不断改进以提供最佳性能。The Azure Cosmos DB SDKs are constantly being improved to provide the best performance. 若要确定最新的 SDK 并查看改进内容,请参阅 Azure Cosmos DB SDKTo determine the most recent SDK and review improvements, see Azure Cosmos DB SDK.

使用流 APIUse stream APIs

.NET SDK V3 包含的流 API 可以在不序列化的情况下接收和返回数据。.NET SDK V3 contains stream APIs that can receive and return data without serializing.

如果中间层应用程序不直接使用 SDK 的响应,而是将其中继到其他应用程序层,则此类应用程序可以受益于流 API。Middle-tier applications that don't consume responses directly from the SDK but relay them to other application tiers can benefit from the stream APIs. 有关流处理的示例,请参阅项管理示例。For examples of stream handling, see the item management samples.

在应用程序生存期内使用单一实例 Azure Cosmos DB 客户端Use a singleton Azure Cosmos DB client for the lifetime of your application

每个 CosmosClient 实例都是线程安全的,在直接模式下运行时可以进行高效的连接管理和地址缓存。Each CosmosClient instance is thread-safe and performs efficient connection management and address caching when it operates in Direct mode. 若要实现有效的连接管理和提高 SDK 客户端性能,建议在应用程序的生存期内对每个 AppDomain 使用单个实例。To allow efficient connection management and better SDK client performance, we recommend that you use a single instance per AppDomain for the lifetime of the application.

使用 Azure Functions 时,实例还应遵循现有指南并维护单个实例。When you're working on Azure Functions, instances should also follow the existing guidelines and maintain a single instance.

禁用写入操作时的内容响应Disable content response on write operations

对于具有大量创建有效负载的工作负荷,请将 EnableContentResponseOnWrite 请求选项设置为 falseFor workloads that have heavy create payloads, set the EnableContentResponseOnWrite request option to false. 该服务将不再将创建或更新的资源返回给 SDK。The service will no longer return the created or updated resource to the SDK. 通常,因为应用程序具有正在创建的对象,因此不需要服务即可将其返回。Normally, because the application has the object that's being created, it doesn't need the service to return it. 标头值仍可访问,例如请求费用。The header values are still accessible, like a request charge. 禁用内容响应有助于提高性能,因为 SDK 不再需要分配内存或序列化响应正文。Disabling the content response can help improve performance, because the SDK no longer needs to allocate memory or serialize the body of the response. 此外还会降低网络带宽的使用率,从而进一步提高性能。It also reduces the network bandwidth usage to further help performance.

ItemRequestOption requestOptions = new ItemRequestOptions() { EnableContentResponseOnWrite = false };
ItemResponse<Book> itemResponse = await this.container.CreateItemAsync<Book>(book, new PartitionKey(book.pk), requestOptions);
// Resource will be null
itemResponse.Resource

启用 Bulk 以优化吞吐量,而不是优化延迟Enable Bulk to optimize for throughput instead of latency

对于工作负荷需要大吞吐量且延迟不是那么重要的场景,请启用“Bulk”。Enable Bulk for scenarios where the workload requires a large amount of throughput, and latency is not as important. 若要详细了解如何启用 Bulk 功能,并了解应将其用于哪些场景,请参阅 Bulk 支持简介For more information about how to enable the Bulk feature, and to learn which scenarios it should be used for, see Introduction to Bulk support.

在使用网关模式时增大每台主机的 System.Net MaxConnectionsIncrease System.Net MaxConnections per host when you use Gateway mode

使用网关模式时,Azure Cosmos DB 请求是通过 HTTPS/REST 发出的。Azure Cosmos DB requests are made over HTTPS/REST when you use Gateway mode. 这些请求受制于每个主机名或 IP 地址的默认连接限制。They're subject to the default connection limit per hostname or IP address. 可能需要将 MaxConnections 设置为较大的值(从 100 到 1,000),以便客户端库能够同时使用多个连接来访问 Azure Cosmos DB。You might need to set MaxConnections to a higher value (from 100 through 1,000) so that the client library can use multiple simultaneous connections to Azure Cosmos DB. 在 .NET SDK 1.8.0 及更高版本中,ServicePointManager.DefaultConnectionLimit 的默认值为 50。In .NET SDK 1.8.0 and later, the default value for ServicePointManager.DefaultConnectionLimit is 50. 若要更改该值,可以将 Documents.Client.ConnectionPolicy.MaxConnectionLimit 设置为较高的值。To change the value, you can set Documents.Client.ConnectionPolicy.MaxConnectionLimit to a higher value.

优化已分区集合的并行查询Tune parallel queries for partitioned collections

SQL .NET SDK 支持并行查询,使你能够并行查询分区的容器。SQL .NET SDK supports parallel queries, which enable you to query a partitioned container in parallel. 有关详细信息,请参阅与使用这些 SDK 相关的代码示例For more information, see code samples related to working with the SDKs. 并行查询旨在提供更低的查询延迟,以及优于其对应的串行查询的吞吐量。Parallel queries are designed to provide better query latency and throughput than their serial counterpart.

并行查询提供两个参数,你可以根据要求优化这些参数:Parallel queries provide two parameters that you can tune to fit your requirements:

  • MaxConcurrency:控制可以并行查询的最大分区数。MaxConcurrency: Controls the maximum number of partitions that can be queried in parallel.

    并行查询的工作原理是并行查询多个分区。Parallel query works by querying multiple partitions in parallel. 但就查询本身而言,会按顺序提取单个分区中的数据。But data from an individual partition is fetched serially with respect to the query. SDK V3 中的 MaxConcurrency 设置为分区数最有可能实现最高性能的查询,前提是所有其他的系统条件保持不变。Setting MaxConcurrency in SDK V3 to the number of partitions has the best chance of achieving the most performant query, provided all other system conditions remain the same. 如果不知道分区数,可将并行度设置为较大的数字。If you don't know the number of partitions, you can set the degree of parallelism to a high number. 系统会选择最小值(分区数、用户提供的输入)作为并行度。The system will choose the minimum (number of partitions, user provided input) as the degree of parallelism.

    如果查询时数据均衡分布在所有分区之间,则并行查询的优势最大。Parallel queries produce the most benefit if the data is evenly distributed across all partitions with respect to the query. 如果对已分区的集合进行分区,使查询返回的全部或大部分数据集中于几个分区(最坏的情况为一个分区),则这些分区会使查询性能出现瓶颈。If the partitioned collection is partitioned so that all or most of the data returned by a query is concentrated in a few partitions (one partition is the worst case), those partitions will bottleneck the performance of the query.

  • MaxBufferedItemCount:控制预提取的结果数。MaxBufferedItemCount: Controls the number of pre-fetched results.

    并行查询设计为当客户端正在处理当前结果批时预提取结果。Parallel query is designed to pre-fetch results while the current batch of results is being processed by the client. 这种预提取可帮助改善查询的总体延迟。This pre-fetching helps improve the overall latency of a query. MaxBufferedItemCount 参数限制预提取的结果数。The MaxBufferedItemCount parameter limits the number of pre-fetched results. MaxBufferedItemCount 设置为预期返回的结果数(或更大的数字)可让查询通过预提取获得最大优势。Set MaxBufferedItemCount to the expected number of results returned (or a higher number) to allow the query to receive the maximum benefit from pre-fetching.

    预提取的工作方式与并行度无关,使用一个单独的缓冲区来存储所有分区的数据。Pre-fetching works the same way regardless of the degree of parallelism, and there's a single buffer for the data from all partitions.

按 RetryAfter 间隔实现退让Implement backoff at RetryAfter intervals

在性能测试期间,应该增加负载,直到系统对小部分请求进行限制为止。During performance testing, you should increase load until a small rate of requests are throttled. 如果请求受到限制,客户端应用程序应按照服务器指定的重试间隔在限制时退让。If requests are throttled, the client application should back off throttling for the server-specified retry interval. 允许退让有助于确保最大程度地减少等待重试的时间。Respecting the backoff helps ensure that you'll spend a minimal amount of time waiting between retries.

有关详细信息,请参阅 RetryAfterFor more information, see RetryAfter.

有一个机制可以记录附加诊断信息和排查延迟问题,如以下示例所示。There's a mechanism for logging additional diagnostics information and troubleshooting latency issues, as shown in the following sample. 可以记录具有较高读取延迟的请求的诊断字符串。You can log the diagnostics string for requests that have a higher read latency. 捕获的诊断字符串可帮助你了解收到给定请求的 429 错误的次数。The captured diagnostics string will help you understand how many times you received a 429 error for a given request.

ItemResponse<Book> readItemResponse = await this.cosmosContainer.ReadItemAsync<Book>("ItemId", new PartitionKey("PartitionKeyValue"));
readItemResponse.Diagnostics.ToString(); 

增加线程/任务数目Increase the number of threads/tasks

请参阅本文“网络”部分中的增加线程/任务数目See Increase the number of threads/tasks in the Networking section of this article.

索引策略Indexing policy

从索引中排除未使用的路径以加快写入速度Exclude unused paths from indexing for faster writes

Azure Cosmos DB 的索引策略还允许使用索引路径(IndexingPolicy.IncludedPaths 和 IndexingPolicy.ExcludedPaths)指定要在索引中包括或排除的文档路径。The Azure Cosmos DB indexing policy also allows you to specify which document paths to include or exclude from indexing by using indexing paths (IndexingPolicy.IncludedPaths and IndexingPolicy.ExcludedPaths).

在事先已知查询模式的情况下,仅对所需路径编制索引可以提高写入性能,减少写入操作时的 RU 费用和索引存储。Indexing only the paths you need can improve write performance, reduce RU charges on write operations, and reduce index storage for scenarios in which the query patterns are known beforehand. 这是因为,索引成本与已编制索引的唯一路径数目直接相关。This is because indexing costs correlate directly to the number of unique paths indexed. 例如,以下代码演示了如何使用“*”通配符从索引中排除整个文档部分(子树):For example, the following code shows how to exclude an entire section of the documents (a subtree) from indexing by using the "*" wildcard:

var containerProperties = new ContainerProperties(id: "excludedPathCollection", partitionKeyPath: "/pk" );
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
Container container = await this.cosmosDatabase.CreateContainerAsync(containerProperties);

有关索引的详细信息,请参阅 Azure Cosmos DB 索引策略For more information, see Azure Cosmos DB indexing policies.

吞吐量Throughput

度量和优化 RU/秒使用量较低的情况Measure and tune for lower RU/s usage

Azure Cosmos DB 提供一组丰富的数据库操作。Azure Cosmos DB offers a rich set of database operations. 这些操作包括通用磁盘格式 (UDF) 文件的关系和分层查询、存储过程和触发器,全都在数据库集合中的文档上进行。These operations include relational and hierarchical queries with Universal Disk Format (UDF) files, stored procedures, and triggers, all operating on the documents within a database collection.

与其中每个操作关联的成本取决于完成该操作所需的 CPU、IO 和内存。The costs associated with each of these operations vary depending on the CPU, IO, and memory that are required to complete the operation. 可以考虑将请求单位作为所需资源的单个度量,以便执行各种数据库操作和服务应用程序请求,而不必考虑和管理硬件资源。Instead of thinking about and managing hardware resources, you can think of a Request Unit as a single measure for the resources that are required to perform various database operations and service an application request.

吞吐量的预配取决于为每个容器设置的请求单位数。Throughput is provisioned based on the number of Request Units set for each container. 请求单位消耗以每秒单位数速率进行评估。Request Unit consumption is evaluated as a units-per-second rate. 如果应用程序的速率超过了为其容器预配的请求单位速率,则会受到限制,直到该速率降到容器的预配级别以下。Applications that exceed the provisioned Request Unit rate for their container are limited until the rate drops below the provisioned level for the container. 如果应用程序需要较高级别的吞吐量,可以通过预配更多请求单位来增加吞吐量。If your application requires a higher level of throughput, you can increase your throughput by provisioning additional Request Units.

查询的复杂性会影响操作消耗的请求单位数量。The complexity of a query affects how many Request Units are consumed for an operation. 谓词数、谓词性质、UDF 文件数目和源数据集的大小都会影响查询操作的成本。The number of predicates, the nature of the predicates, the number of UDF files, and the size of the source dataset all influence the cost of query operations.

若要度量任一操作(创建、更新或删除)的开销,请检查 x-ms-request-charge 标头(或者 .NET SDK 的 ResourceResponse\<T>FeedResponse\<T> 中的等效 RequestCharge 属性),以度量这些操作消耗的请求单位数:To measure the overhead of any operation (create, update, or delete), inspect the x-ms-request-charge header (or the equivalent RequestCharge property in ResourceResponse\<T> or FeedResponse\<T> in the .NET SDK) to measure the number of Request Units consumed by the operations:

// Measure the performance (Request Units) of writes
ItemResponse<Book> response = await container.CreateItemAsync<Book>(myBook, new PartitionKey(myBook.PkValue));
Console.WriteLine("Insert of item consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
FeedIterator<Book> queryable = container.GetItemQueryIterator<ToDoActivity>(queryString);
while (queryable.HasMoreResults)
    {
        FeedResponse<Book> queryResponse = await queryable.ExecuteNextAsync<Book>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

在此标头中返回的请求费用是已预配吞吐量(即 2,000 RU/秒)的一小部分。The request charge that's returned in this header is a fraction of your provisioned throughput (that is, 2,000 RU/s). 例如,如果上述查询返回 1,000 个 1-KB 的文档,则操作成本是 1,000。For example, if the preceding query returns 1,000 1-KB documents, the cost of the operation is 1,000. 因此,在一秒内,服务器在对后续请求进行速率限制之前只接受两个此类请求。So, within one second, the server honors only two such requests before it rate-limits later requests. 有关详细信息,请参阅请求单位请求单位计算器For more information, see Request Units and the Request Unit calculator.

处理速率限制/请求速率太大Handle rate limiting/request rate too large

客户端尝试超过为帐户保留的吞吐量时,服务器的性能不会降低,并且不会使用超过保留级别的吞吐量容量。When a client attempts to exceed the reserved throughput for an account, there's no performance degradation at the server and no use of throughput capacity beyond the reserved level. 服务器会提前结束请求并返回 RequestRateTooLarge(HTTP 状态代码为 429)错误。The server preemptively ends the request with RequestRateTooLarge (HTTP status code 429). 它会返回 x-ms-retry-after-ms 标头,指示重试该请求之前用户必须等待的时间(以毫秒为单位)。It returns an x-ms-retry-after-ms header that indicates the amount of time, in milliseconds, that the user must wait before attempting the request again.

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

SDK 全部都会隐式捕获此响应,并遵循服务器指定的 retry-after 标头,并重试请求。The SDKs all implicitly catch this response, respect the server-specified retry-after header, and retry the request. 除非多个客户端同时访问帐户,否则下次重试就会成功。Unless your account is being accessed concurrently by multiple clients, the next retry will succeed.

如果累计有多个客户端持续在超过请求速率的情况下运行,则当前由客户端在内部设置为 9 的默认重试计数可能并不够用。If you have more than one client cumulatively operating consistently above the request rate, the default retry count that's currently set to 9 internally by the client might not suffice. 在这种情况下,客户端会向应用程序引发 CosmosException,状态代码为 429。In this case, the client throws a CosmosException with status code 429 to the application.

可以通过在 CosmosClientOptions 实例上设置 RetryOptions 来更改默认重试计数。You can change the default retry count by setting the RetryOptions on the CosmosClientOptions instance. 默认情况下,如果请求继续以高于请求速率的方式运行,则会在 30 秒的累积等待时间后返回 CosmosException,状态代码为 429。By default, the CosmosException with status code 429 is returned after a cumulative wait time of 30 seconds if the request continues to operate above the request rate. 即使当前的重试计数小于最大重试计数(无论当前值是默认值 9 还是用户定义的值),也会返回此错误。This error is returned even when the current retry count is less than the maximum retry count, whether the current value is the default of 9 or a user-defined value.

自动重试行为有助于改善大多数应用程序的复原能力和可用性。The automated retry behavior helps improve resiliency and usability for most applications. 但是,在执行性能基准测试时(尤其是在度量延迟时),自动重试可能不是最佳行为。But it might not be the best behavior when you're doing performance benchmarks, especially when you're measuring latency. 如果实验达到服务器限制并导致客户端 SDK 静默重试,则客户端观测到的延迟会剧增。The client-observed latency will spike if the experiment hits the server throttle and causes the client SDK to silently retry. 若要避免性能实验期间出现延迟高峰,可以测量每个操作返回的费用,确保请求以低于保留请求速率的方式运行。To avoid latency spikes during performance experiments, measure the charge that's returned by each operation, and ensure that requests are operating below the reserved request rate.

有关详细信息,请参阅请求单位For more information, see Request Units.

针对较小文档进行设计以提高吞吐量For higher throughput, design for smaller documents

指定操作的请求费用(即请求处理成本)与文档大小直接相关。The request charge (that is, the request-processing cost) of a specified operation correlates directly to the size of the document. 大型文档的操作成本高于小型文档的操作成本。Operations on large documents cost more than operations on small documents.

后续步骤Next steps

如果需要使用一个示例应用程序来评估 Azure Cosmos DB,以便在数个客户端计算机上实现高性能方案,请参阅使用 Azure Cosmos DB 进行性能和缩放测试For a sample application that's used to evaluate Azure Cosmos DB for high-performance scenarios on a few client machines, see Performance and scale testing with Azure Cosmos DB.

若要深入了解如何设计应用程序以实现缩放和高性能,请参阅 Azure Cosmos DB 中的分区和缩放To learn more about designing your application for scale and high performance, see Partitioning and scaling in Azure Cosmos DB.