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

Azure Cosmos DB 是一个快速、弹性的分布式数据库,可以在提供延迟与吞吐量保证的情况下无缝缩放。Azure Cosmos DB is a fast and flexible distributed database that scales seamlessly with guaranteed latency and throughput. 凭借 Azure Cosmos DB,无需对体系结构进行重大更改或编写复杂的代码即可缩放数据库。You do not 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 how to provision container throughput or how to provision database throughput. 但是,由于 Azure Cosmos DB 是通过网络调用访问的,因此,使用 SQL .NET SDK 时可以通过进行客户端优化来获得最高性能。However, because Azure Cosmos DB is accessed via network calls there are client-side optimizations you can make to achieve peak performance when using the SQL .NET SDK.

如果有“如何改善数据库性能?”的疑问,So if you're asking "How can I improve my database performance?" 请考虑以下选项:consider the following options:

网络Networking

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

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

    • 网关模式Gateway mode

      网关模式受所有 SDK 平台支持并已配置为 Microsoft.Azure.DocumentDB SDK 的默认设置。Gateway mode is supported on all SDK platforms and is the configured default for Microsoft.Azure.DocumentDB SDK. 如果应用程序在有严格防火墙限制的企业网络中运行,则网关模式是最佳选择,因为它使用标准 HTTPS 端口与单个终结点。If your application runs within a corporate network with strict firewall restrictions, gateway mode is the best choice since 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 or written to Azure Cosmos DB. 因此,直接模式因为网络跃点较少,可以提供更好的性能。Because of this, Direct Mode offers better performance due to fewer network hops. 在套接字连接数量有限的环境中运行应用程序时,也建议使用网关连接模式。Gateway connection mode is also recommended when you run applications in environments with limited number of socket connections.

      在 Azure Functions 中使用 SDK 时,尤其是在消耗计划中使用时,请注意当前的连接限制When using the SDK in Azure Functions, particularly in consumption plan, be mindful of the current limits in connections. 这种情况下,如果还在 Azure Functions 应用程序中使用其他基于 HTTP 的客户端,则建议使用网关模式。In that case, gateway mode might be recommended if you are also working with other HTTP based clients within your Azure Functions application.

    • 直接模式Direct mode

      直接模式支持通过 TCP 协议进行连接,并且在使用 Microsoft.Azure.Cosmos/.Net V3 SDK 的情况下是默认的连接模式。Direct mode supports connectivity through TCP protocol and is the default connectivity mode if you are using Microsoft.Azure.Cosmos/.Net V3 SDK.

      如果使用网关模式,Cosmos DB 在使用 Azure Cosmos DB 的 API for MongoDB 时使用端口 443 和端口 10250、10255 和 10256。When using gateway mode, Cosmos DB uses port 443 and ports 10250, 10255 and 10256 when using Azure Cosmos DB's API for MongoDB. 10250 端口映射到没有异地复制功能的默认 MongoDB 实例,10255/10256 端口映射到具有异地复制功能的 MongoDB 实例。The 10250 port maps to a default MongoDB instance without geo-replication and 10255/10256 ports map to the MongoDB instance with geo-replication functionality. 在直接模式下使用时 TCP 时,除了网关端口外,还需确保端口 10000 到 20000 范围之间的端口处于打开状态,因为 Azure Cosmos DB 使用动态 TCP 端口。When using TCP in Direct Mode, in addition to the Gateway ports, you need to ensure the port range between 10000 and 20000 is open because Azure Cosmos DB uses dynamic TCP ports. 如果这些端口未处于打开状态,则会在尝试使用 TCP 时收到“503 服务不可用”错误。If these ports are not open and you attempt to use TCP, you receive a 503 Service Unavailable error. 下表显示可用于不同 API 的连接模式以及每个 API 的服务端口用户:The following table shows connectivity modes available for different APIs and the service ports user for each API:

      连接模式Connection mode 支持的协议Supported protocol 支持的 SDKSupported SDKs API/服务端口API/Service port
      网关Gateway HTTPSHTTPS 所有 SDKAll SDKS SQL(443)、Mongo(10250, 10255, 10256)、Table(443)、Cassandra(10350)、Graph(443)SQL(443), Mongo(10250, 10255, 10256), Table(443), Cassandra(10350), Graph(443)
      直接Direct TCPTCP .NET SDK.NET SDK 10,000-20,000 范围内的端口Ports within 10,000-20,000 range

      Azure Cosmos DB 提供基于 HTTPS 的简单开放 RESTful 编程模型。Azure Cosmos DB offers a simple and 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 协议使用 SSL 进行初始身份验证以及加密通信。TCP protocol uses SSL for initial authentication and encrypting traffic. 为了获得最佳性能,请尽可能使用 TCP 协议。For best performance, use the TCP protocol when possible.

      在 SDK V3 中,连接模式是在创建 CosmosClient 实例时配置的,作为 CosmosClientOptions 的一部分,请记住直接模式是默认模式。For SDK V3, the connectivity mode is configured while creating the CosmosClient instance, as part of the CosmosClientOptions, remember that Direct mode is the default.

      var serviceEndpoint = new Uri("https://contoso.documents.azure.cn");
      var authKey = "your authKey from the Azure portal";
      CosmosClient client = new CosmosClient(serviceEndpoint, authKey,
      new CosmosClientOptions
      {
          ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
      });
      

      对于 Microsoft.Azure.DocumentDB SDK,连接模式在构造 DocumentClient 实例期间使用 ConnectionPolicy 参数配置。For the Microsoft.Azure.DocumentDB SDK, the connectivity mode is configured during the construction of the DocumentClient instance with the ConnectionPolicy parameter. 如果使用直接模式,则也可以在 ConnectionPolicy 参数中设置协议。If Direct Mode is used, the Protocol can also be set within the ConnectionPolicy parameter.

      var serviceEndpoint = new Uri("https://contoso.documents.azure.cn");
      var authKey = "your authKey from the Azure portal";
      DocumentClient client = new DocumentClient(serviceEndpoint, authKey,
      new ConnectionPolicy
      {
          ConnectionMode = ConnectionMode.Direct, //ConnectionMode.Gateway is the default
          ConnectionProtocol = Protocol.Tcp
      });
      

      由于只有直接模式支持 TCP,因此如果使用网关模式,HTTPS 协议始终用来与网关通信,并忽略 ConnectionPolicy 中的 Protocol 值。Because TCP is only supported in Direct Mode, if gateway mode is used, then the HTTPS protocol is always used to communicate with the Gateway and the Protocol value in the ConnectionPolicy is ignored.

      Azure Cosmos DB 连接策略演示

  2. 调用 OpenAsync 以避免首次请求时启动延迟Call OpenAsync to avoid startup latency on first request

    默认情况下,第一个请求因为必须提取地址路由表而有较高的延迟。By default, the first request has a higher latency because it has to fetch the address routing table. 使用 SDK V2 时,为了避免首次请求时的这种启动延迟,应该在初始化期间调用 OpenAsync() 一次,如下所示。When using the SDK V2, to avoid this startup latency on the first request, you should call OpenAsync() once during initialization as follows.

     await client.OpenAsync();
    

    备注

    OpenAsync 方法会生成多个请求,这些请求用于获取帐户中所有容器的地址路由表。OpenAsync method will generate requests to obtain the address routing table for all the containers in the account. 如果帐户有多个容器,但其应用程序访问的是其中的一部分,则会产生不必要的流量,导致初始化速度慢。For accounts that have many containers but their application accesses a subset of them, it would generate an unnecessary amount of traffic that makes the initialization slow. 因此,在这种情况下使用 OpenAsync 方法可能没有用,因为它会降低应用程序启动速度。So using OpenAsync method might not be useful in this scenario as it slows down application startup.

  3. 将客户端并置在同一 Azure 区域中以提高性能Collocate clients in same Azure region for performance

    如果可能,请将任何调用 Azure Cosmos DB 的应用程序放在与 Azure Cosmos 数据库所在的相同区域中。When possible, place any applications calling Azure Cosmos DB in the same region as the Azure Cosmos database. 根据请求采用的路由,各项请求从客户端传递到 Azure 数据中心边界时的此类延迟可能有所不同。This latency can likely 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 区域中调用应用程序,可能会实现最低的延迟。The lowest possible latency is achieved by ensuring the calling application is located within the same Azure region as the provisioned Azure Cosmos DB endpoint. 有关可用区域的列表,请参阅 Azure Regions(Azure 区域)。For a list of available regions, see Azure Regions.

    Azure Cosmos DB 连接策略演示

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

    由于对 Cosmos DB 的调用是通过网络执行的,因此可能需要改变请求的并行度,以便最大程度地减少客户端应用程序等待请求的时间。Since calls to Azure Cosmos DB are made over the network, you may need to vary the degree of parallelism of your requests so that the client application spends very little time waiting between requests. 例如,如果使用的是 .NET 的任务并行库,请创建大约数百个读取或写入 Azure Cosmos DB 的任务。For example, if you're using .NET's Task Parallel Library, create in the order of 100s of Tasks reading or writing to Azure Cosmos DB.

  5. 启用加速网络Enable accelerated networking

    为了降低延迟和 CPU 抖动情况,建议为客户端虚拟机启用加速网络。In order to reduce latency and CPU jitter, we recommend that the client virtual machines are accelerated networking enabled. 请参阅创建具有加速网络的 Windows 虚拟机创建具有加速网络的 Linux 虚拟机一文,了解如何启用加速网络。See the Create a Windows virtual machine with Accelerated Networking or Create a Linux virtual machine with Accelerated Networking articles to enable accelerated networking.

SDK 用法SDK Usage

  1. 安装最新的 SDKInstall the most recent SDK

    Azure Cosmos DB SDK 正在不断改进以提供最佳性能。The Azure Cosmos DB SDKs are constantly being improved to provide the best performance. 请参阅 Azure Cosmos DB SDK 页以了解最新的 SDK 并查看改进内容。See the Azure Cosmos DB SDK pages to determine the most recent SDK and review improvements.

  2. 使用流 APIUse Stream APIs

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

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

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

    每个 DocumentClient 和 CosmosClient 实例都是线程安全的,在直接模式下运行时可执行高效的连接管理和地址缓存。Each DocumentClient and CosmosClient instance is thread-safe and performs efficient connection management and address caching when operating in direct mode. 若要通过 SDK 客户端获得高效的连接管理和更好的性能,建议在应用程序生存期内对每个 AppDomain 使用单个实例。To allow efficient connection management and better performance by the SDK client, it is recommended to use a single instance per AppDomain for the lifetime of the application.

  4. 在使用“网关”模式时增加每台主机的 System.Net MaxConnectionsIncrease System.Net MaxConnections per host when using Gateway mode

    使用“网关”模式时,Azure Cosmos DB 请求是通过 HTTPS/REST 发出的,并且受制于每个主机名或 IP 地址的默认连接限制。Azure Cosmos DB requests are made over HTTPS/REST when using Gateway mode, and are subjected to the default connection limit per hostname or IP address. 可能需要将 MaxConnections 设置为较大的值 (100-1000),以便客户端库能够同时利用多个连接来访问 Azure Cosmos DB。You may need to set the MaxConnections to a higher value (100-1000) so that the client library can utilize multiple simultaneous connections to Azure Cosmos DB. 在 .NET SDK 1.8.0 和更高版本中,ServicePointManager.DefaultConnectionLimit 的默认值为 50,要更改此值,可将 Documents.Client.ConnectionPolicy.MaxConnectionLimit 设置为更大的值。In the .NET SDK 1.8.0 and above, the default value for ServicePointManager.DefaultConnectionLimit is 50 and to change the value, you can set the Documents.Client.ConnectionPolicy.MaxConnectionLimit to a higher value.

  5. 优化分区集合的并行查询。Tuning parallel queries for partitioned collections

    SQL .NET SDK 版本 1.9.0 和更高版本支持并行查询,使你能够并行查询分区集合。SQL .NET SDK version 1.9.0 and above support parallel queries, which enable you to query a partitioned collection in parallel. 有关详细信息,请参阅与使用这些 SDK 相关的代码示例For more information, see code samples related to working with the SDKs. 并行查询旨改善查询延迟和串行配对物上的吞吐量。Parallel queries are designed to improve query latency and throughput over their serial counterpart. 并行查询提供两个参数,用户可以调整来适应自身的需求 (a) MaxDegreeOfParallelism:控制并行中运行的最大分区数 (b) MaxBufferedItemCount:控制预提取结果的数量。Parallel queries provide two parameters that users can tune to custom-fit their requirements, (a) MaxDegreeOfParallelism: to control the maximum number of partitions then can be queried in parallel, and (b) MaxBufferedItemCount: to control the number of pre-fetched results.

    (a) 优化并行度: 并行查询通过查询并行中的多个分区来运行。(a) Tuning degree of parallelism: Parallel query works by querying multiple partitions in parallel. 但就查询本身而言,会按顺序提取单个分区中的数据。However, data from an individual partition is fetched serially with respect to the query. SDK V2 中的 MaxDegreeOfParallelismSDK V3 中的 MaxConcurrency 设置为分区数最有可能实现最高性能的查询,前提是其他所有系统条件保持不变。Setting the MaxDegreeOfParallelism in SDK V2 or MaxConcurrency in SDK V3 to the number of partitions has the maximum 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, and the system chooses the minimum (number of partitions, user provided input) as the degree of parallelism.

    必须注意,如果查询时数据均衡分布在所有分区之间,则并行查询可提供最大的优势。It is important to note that parallel queries produce the best benefits if the data is evenly distributed across all partitions with respect to the query. 如果对分区集合进行分区,其中全部或大部分查询所返回的数据集中于几个分区(最坏的情况下为一个分区),则这些分区会遇到查询的性能瓶颈。If the partitioned collection is partitioned such a way that all or a majority of the data returned by a query is concentrated in a few partitions (one partition in worst case), then the performance of the query would be bottlenecked by those partitions.

    (b) 优化 MaxBufferedItemCount: 并行查询旨在客户端处理结果的当前批时预提取结果。(b) Tuning MaxBufferedItemCount: Parallel query is designed to pre-fetch results while the current batch of results is being processed by the client. 预提取帮助改进查询中的的总体延迟。The pre-fetching helps in overall latency improvement of a query. MaxBufferedItemCount 是用于限制预先提取的结果数的参数。MaxBufferedItemCount is the parameter to limit the number of pre-fetched results. 将 MaxBufferedItemCount 设置为预期返回的结果数目(或更高的数目),可让查询通过预先提取获得最大优势。Setting MaxBufferedItemCount to the expected number of results returned (or a higher number) allows the query to receive maximum benefit from pre-fetching.

    预提取的工作方式不因并行度而异,并且有一个单独的缓冲区用来存储所有分区的数据。Pre-fetching works the same way irrespective of the degree of parallelism, and there is a single buffer for the data from all partitions.

  6. 打开服务器端 GCTurn on server-side GC

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

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

    在性能测试期间,应该增加负载,直到系统对小部分请求进行限制为止。During performance testing, you should increase load until a small rate of requests get throttled. 如果受到限制,客户端应用程序应按照服务器指定的重试间隔在限制时退让。If throttled, the client application should backoff on throttle for the server-specified retry interval. 遵循退让可确保最大程度地减少等待重试的时间。Respecting the backoff ensures that you spend minimal amount of time waiting between retries. 重试策略支持包含在 SQL .NETJava 1.8.0 和更高版本中,以及 Node.jsPython 1.9.0 或更高版本以及所有受支持的 .NET Core SDK 版本中。Retry policy support is included in Version 1.8.0 and above of the SQL .NET and Java, version 1.9.0 and above of the Node.js and Python, and all supported versions of the .NET Core SDKs. 有关详细信息,请参阅 RetryAfterFor more information, RetryAfter.

    使用 .NET SDK 1.19 版和更高版本时,存在一种机制来记录附加诊断信息和排查延迟问题,如以下示例所示。With version 1.19 and later of the .NET SDK, there is a mechanism to log additional diagnostic information and troubleshoot latency issues as shown in the following sample. 可以记录具有较高读取延迟的请求的诊断字符串。You can log the diagnostic string for requests that have a higher read latency. 捕获的诊断字符串将帮助你了解观察到给定请求延迟 429 秒的次数。The captured diagnostic string will help you understand the number of times you observed 429s for a given request.

    ResourceResponse<Document> readDocument = await this.readClient.ReadDocumentAsync(oldDocuments[i].SelfLink);
    readDocument.RequestDiagnosticsString 
    
  8. 增大客户端工作负荷Scale out your client-workload

    如果以高吞吐量级别(> 50,000 RU/秒)进行测试,客户端应用程序可能成为瓶颈,因为计算机的 CPU 或网络利用率将达到上限。If you are testing at high throughput levels (>50,000 RU/s), the client application may become the bottleneck due to the machine capping 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.

  9. 缓存较低读取延迟的文档 URICache document URIs for lower read latency

    尽可能缓存文档 URI 以获得最佳读取性能。Cache document URIs whenever possible for the best read performance. 创建资源时,必须定义逻辑才能缓存 resourceid。You have to define logic to cache the resourceid when you create the resource. 基于 resourceid 的查找比基于名称的查找更快,因此缓存这些值可提高性能。Resourceid based lookups are faster than name based lookups, so caching these values improves the performance.

  10. 调整查询/读取源的页面大小以获得更好的性能Tune the page size for queries/read feeds for better performance

    使用读取源功能(例如,ReadDocumentFeedAsync)执行批量文档读取时,或发出 SQL 查询时,如果结果集太大,则以分段方式返回结果。When performing a bulk read of documents using read feed functionality (for example, ReadDocumentFeedAsync) or when issuing a SQL query, the results are returned in a segmented fashion if the result set is too large. 默认情况下,以包括 100 个项的块或 1 MB 大小的块返回结果(以先达到的限制为准)。By default, results are returned in chunks of 100 items or 1 MB, whichever limit is hit first.

    若要减少检索所有适用结果所需的网络往返次数,可以使用 x-ms-max-item-count 请求标头将页面大小最大增加到 1000。To reduce the number of network round trips required to retrieve all applicable results, you can increase the page size using x-ms-max-item-count request header to up to 1000. 在只需要显示几个结果的情况下(例如,用户界面或应用程序 API 一次只返回 10 个结果),也可以将页面大小缩小为 10,以降低读取和查询所耗用的吞吐量。In cases where you need to display only a few results, for example, if your user interface or application API returns only 10 results a time, you can also decrease the page size to 10 to reduce the throughput consumed for reads and queries.

    备注

    maxItemCount 属性不应仅用于分页目的。The maxItemCount property shouldn't be used just for pagination purpose. 它的主要用途是通过减少单个页面中返回的最大项数来提高查询性能。It's main usage it to improve the performance of queries by reducing the maximum number of items returned in a single page.

    也可以使用可用的 Azure Cosmos DB SDK 设置页面大小。You can also set the page size using the available Azure Cosmos DB SDKs. FeedOptions 中的 MaxItemCount 属性允许你设置要在枚举操作中返回的最大项数。The MaxItemCount property in FeedOptions allows you to set the maximum number of items to be returned in the enumeration operation. maxItemCount 设置为 -1 时,SDK 会根据文档大小自动查找最佳值。When maxItemCount is set to -1, the SDK automatically finds the most optimal value depending on the document size. 例如:For example:

    IQueryable<dynamic> authorResults = client.CreateDocumentQuery(documentCollection.SelfLink, "SELECT p.Author FROM Pages p WHERE p.Title = 'About Seattle'", new FeedOptions { MaxItemCount = 1000 });
    

    执行查询时,结果数据在 TCP 数据包中发送。When a query is executed, the resulting data is sent within a TCP packet. 如果为 maxItemCount 指定的值太低,则在 TCP 数据包中发送数据所需的往返次数很高,这会影响性能。If you specify too low value for maxItemCount, the number of trips required to send the data within the TCP packet are high, which impacts the performance. 因此,如果你不确定要为 maxItemCount 属性设置什么值,最好将其设置为 -1,然后让 SDK 选择默认值。So if you are not sure what value to set for maxItemCount property, it's best to set it to -1 and let the SDK choose the default value.

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

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

  12. 使用 64 位主机进程Use 64-bit host processing

    当用户使用 SQL .NET SDK 1.11.4 及更高版本时,SQL SDK 可以在 32 位主机进程中运行。The SQL SDK works in a 32-bit host process when you are using SQL .NET SDK version 1.11.4 and above. 但是,如果使用跨分区查询,建议使用 64 位主机进程来提高性能。However, if you are using cross partition queries, 64-bit host processing is recommended for improved performance. 以下类型的应用程序默认为 32 位主机进程,为了将其更改为 64 位,请根据应用程序类型执行以下步骤:The following types of applications have 32-bit host process as the default, so in order to change that to 64-bit, follow these steps based on the type of your application:

    • 对于可执行应用程序,在“生成” 选项卡的“项目属性” 窗口中,通过取消“首选 32 位” 选项可实现以上目的。For Executable applications, this can be done by unchecking the Prefer 32-bit option in the Project Properties window, on the Build tab.

    • 对于基于 VSTest 的测试项目,可通过从“Visual Studio 测试” 菜单选项中选择“测试” ->“测试设置” ->“默认处理器体系结构为 X64” 来完成。For VSTest based test projects, this can be done by selecting Test->Test Settings->Default Processor Architecture as X64, from the Visual Studio Test menu option.

    • 对于本地部署的 ASP.NET Web 应用程序,可以通过在“工具”->“选项”->“项目和解决方案”->“Web 项目”下勾选“对网站和项目使用 IIS Express 的 64 位版”来完成。 For locally deployed ASP.NET Web applications, this can be done by checking the Use the 64-bit version of IIS Express for web sites and projects, under Tools->Options->Projects and Solutions->Web Projects.

    • 对于部署在 Azure 上的 ASP.NET Web 应用程序,可以通过在 Azure 门户上的“应用程序设置” 中选择“64 位平台” 来完成。For ASP.NET Web applications deployed on Azure, this can be done by choosing the Platform as 64-bit in the Application Settings on the Azure portal.

索引策略Indexing Policy

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

    Cosmos DB 的索引策略还允许使用索引路径(IndexingPolicy.IncludedPaths 和 IndexingPolicy.ExcludedPaths)指定要在索引中包括或排除的文档路径。Cosmos DB's indexing policy also allows you to specify which document paths to include or exclude from indexing by leveraging Indexing Paths (IndexingPolicy.IncludedPaths and IndexingPolicy.ExcludedPaths). 在事先知道查询模式的方案中,使用索引路径可改善写入性能并降低索引存储空间,因为索引成本与索引的唯一路径数目直接相关。The use of indexing paths can offer improved write performance and lower index storage for scenarios in which the query patterns are known beforehand, as indexing costs are directly correlated 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 using the "*" wildcard.

    var collection = new DocumentCollection { Id = "excludedPathCollection" };
    collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
    collection.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
    collection = await client.CreateDocumentCollectionAsync(UriFactory.CreateDatabaseUri("db"), excluded);
    

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

吞吐量Throughput

  1. 测量和优化较低的每秒请求单位使用量Measure and tune for lower request units/second usage

    Azure Cosmos DB 提供一组丰富的数据库操作,包括 UDF 的关系和层次查询,存储过程和触发器 - 所有这些都是对数据库集合内的文档进行的操作。Azure Cosmos DB offers a rich set of database operations including relational and hierarchical queries with UDFs, stored procedures, and triggers - all operating on the documents within a database collection. 与这些操作关联的成本取决于完成操作所需的 CPU、IO 和内存。The cost associated with each of these operations varies based on the CPU, IO, and memory required to complete the operation. 与考虑和管理硬件资源不同的是,可以考虑将请求单位 (RU) 作为所需资源的单个措施,以执行各种数据库操作和服务应用程序请求。Instead of thinking about and managing hardware resources, you can think of a request unit (RU) as a single measure for the resources 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 rate per second. 如果应用程序的速率超过了为其容器预配的请求单位速率,则会受到限制,直到该速率降到容器的预配级别以下。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 impacts how many Request Units are consumed for an operation. 谓词数、谓词性质、UDF 数目和源数据集的大小都会影响查询操作的成本。The number of predicates, nature of the predicates, number of UDFs, and the size of the source data set 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 these operations.

    // Measure the performance (request units) of writes
    ResourceResponse<Document> response = await client.CreateDocumentAsync(collectionSelfLink, myDocument);
    Console.WriteLine("Insert of document consumed {0} request units", response.RequestCharge);
    // Measure the performance (request units) of queries
    IDocumentQuery<dynamic> queryable = client.CreateDocumentQuery(collectionSelfLink, queryString).AsDocumentQuery();
    while (queryable.HasMoreResults)
         {
              FeedResponse<dynamic> queryResponse = await queryable.ExecuteNextAsync<dynamic>();
              Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
         }
    

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

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

<span data-ttu-id="efe3f-270">客户端尝试超过帐户保留的吞吐量时,服务器的性能不会降低,并且不会使用超过保留级别的吞吐量容量。</span><span class="sxs-lookup"><span data-stu-id="efe3f-270">When a client attempts to exceed the reserved throughput for an account, there is no performance degradation at the server and no use of throughput capacity beyond the reserved level.</span></span> <span data-ttu-id="efe3f-271">服务器将抢先结束 RequestRateTooLarge(HTTP 状态代码 429)的请求并返回 [x-ms-retry-after-ms](https://docs.microsoft.com/rest/api/cosmos-db/common-cosmosdb-rest-response-headers) 标头,该标头指示重新尝试请求前用户必须等待的时间量(以毫秒为单位)。</span><span class="sxs-lookup"><span data-stu-id="efe3f-271">The server will preemptively end the request with RequestRateTooLarge (HTTP status code 429) and return the [x-ms-retry-after-ms](https://docs.microsoft.com/rest/api/cosmos-db/common-cosmosdb-rest-response-headers) header indicating the amount of time, in milliseconds, that the user must wait before reattempting the request.</span></span>

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

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

<span data-ttu-id="efe3f-274">如果存在多个高于请求速率的请求操作,则客户端当前在内部设置为 9 的默认重试计数可能无法满足需要;在此情况下,客户端就会向应用程序引发 DocumentClientException,其状态代码为 429。</span><span class="sxs-lookup"><span data-stu-id="efe3f-274">If you have more than one client cumulatively operating consistently above the request rate, the default retry count currently set to 9 internally by the client may not suffice; in this case, the client throws a DocumentClientException with status code 429 to the application.</span></span> <span data-ttu-id="efe3f-275">可以通过在 ConnectionPolicy 实例上设置 RetryOptions 来更改默认重试计数。</span><span class="sxs-lookup"><span data-stu-id="efe3f-275">The default retry count can be changed by setting the RetryOptions on the ConnectionPolicy instance.</span></span> <span data-ttu-id="efe3f-276">默认情况下,如果请求继续以高于请求速率的方式运行,则在 30 秒的累积等待时间后返回 DocumentClientException 和状态代码 429。</span><span class="sxs-lookup"><span data-stu-id="efe3f-276">By default, the DocumentClientException with status code 429 is returned after a cumulative wait time of 30 seconds if the request continues to operate above the request rate.</span></span> <span data-ttu-id="efe3f-277">即使当前的重试计数小于最大重试计数(默认值 9 或用户定义的值),也会发生这种情况。</span><span class="sxs-lookup"><span data-stu-id="efe3f-277">This occurs even when the current retry count is less than the max retry count, be it the default of 9 or a user-defined value.</span></span>

<span data-ttu-id="efe3f-278">尽管自动重试行为有助于改善大多数应用程序的复原能力和可用性,但是在执行性能基准测试时可能会造成冲突(尤其是在测量延迟时)。</span><span class="sxs-lookup"><span data-stu-id="efe3f-278">While the automated retry behavior helps to improve resiliency and usability for the most applications, it might come at odds when doing performance benchmarks, especially when measuring latency.</span></span>  <span data-ttu-id="efe3f-279">如果实验达到服务器限制并导致客户端 SDK 静默重试,则客户端观测到的延迟会剧增。</span><span class="sxs-lookup"><span data-stu-id="efe3f-279">The client-observed latency will spike if the experiment hits the server throttle and causes the client SDK to silently retry.</span></span> <span data-ttu-id="efe3f-280">若要避免性能实验期间出现延迟高峰,可以测量每个操作返回的费用,并确保请求以低于保留请求速率的方式运行。</span><span class="sxs-lookup"><span data-stu-id="efe3f-280">To avoid latency spikes during performance experiments, measure the charge returned by each operation and ensure that requests are operating below the reserved request rate.</span></span> <span data-ttu-id="efe3f-281">有关详细信息,请参阅[请求单位](request-units.md)。</span><span class="sxs-lookup"><span data-stu-id="efe3f-281">For more information, see [Request units](request-units.md).</span></span>
  1. 针对小型文档进行设计以提高吞吐量Design for smaller documents for higher throughput

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

后续步骤Next steps

有关用于评估 Azure Cosmos DB 以在少量客户端计算机上实现高性能的示例应用程序,请参阅执行 Azure Cosmos DB 缩放和性能测试For a sample application 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 中的分区和缩放Also, to learn more about designing your application for scale and high performance, see Partitioning and scaling in Azure Cosmos DB.