【问题标题】:Azure Cosmos DB - 'Request rate is large. More Request Units may be needed' error while deleting the itemsAzure Cosmos DB - '请求率很大。删除项目时可能需要更多请求单位的错误
【发布时间】:2020-05-20 08:02:18
【问题描述】:

我正在使用以下存储过程从 cosmos db 集合中删除项目。

function bulkDeleteStoredProcedure(query) {
    var collection = getContext().getCollection();
    var collectionLink = collection.getSelfLink();
    var response = getContext().getResponse();
    var responseBody = {
        deleted: 0,
        continuation: true
    };

    // Validate input.
    if (!query) throw new Error("The query is undefined or null.");

    tryQueryAndDelete();

    // Recursively runs the query w/ support for continuation tokens.
    // Calls tryDelete(documents) as soon as the query returns documents.
    function tryQueryAndDelete(continuation) {
        var requestOptions = {continuation: continuation};

        var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, retrievedDocs, responseOptions) {
            if (err) throw err;

            if (retrievedDocs.length > 0) {
                // Begin deleting documents as soon as documents are returned form the query results.
                // tryDelete() resumes querying after deleting; no need to page through continuation tokens.
                //  - this is to prioritize writes over reads given timeout constraints.
                tryDelete(retrievedDocs);
            } else if (responseOptions.continuation) {
                // Else if the query came back empty, but with a continuation token; repeat the query w/ the token.
                tryQueryAndDelete(responseOptions.continuation);
            } else {
                // Else if there are no more documents and no continuation token - we are finished deleting documents.
                responseBody.continuation = false;
                response.setBody(responseBody);
            }
        });

        // If we hit execution bounds - return continuation: true.
        if (!isAccepted) {
            response.setBody(responseBody);
        }
    }

    // Recursively deletes documents passed in as an array argument.
    // Attempts to query for more on empty array.
    function tryDelete(documents) {
        if (documents.length > 0) {
            // Delete the first document in the array.
            var isAccepted = collection.deleteDocument(documents[0]._self, {}, function (err, responseOptions) {
                if (err) throw err;

                responseBody.deleted++;
                documents.shift();
                // Delete the next document in the array.
                tryDelete(documents);
            });

            // If we hit execution bounds - return continuation: true.
            if (!isAccepted) {
                response.setBody(responseBody);
            }
        } else {
            // If the document array is empty, query for more documents.
            tryQueryAndDelete();
        }
    }
}

执行此存储过程时出现以下错误:

无法为容器执行存储过程 BulkDelete 通知:{"code":429,"body":{"code":"429","message":"Message: {\"Errors\":[\"请求率很大。更多的请求单位可能是 需要,所以没有进行任何更改。请稍后重试此请求。 了解详情:http://aka.ms/cosmosdb-error-429\"]}\r\nActivityId: cc616784-03ee-4b10-9481-d62c26e496e4,请求 URI: /apps/2268c937-d7b4-449e-9d76-a2d50d5d3546/services/df84607d-8553-4938-aa0d-913563078a93/partitions/b37017a9-ab2c-4a88-bb51-0ae729299a7e/7336/1382341 RequestStats: \r\nRequestStartTime: 2020-05-20T07:55:16.8899325Z, RequestEndTime:2020-05-20T07:55:17.5299234Z,区域数 尝试:1\r\n响应时间:2020-05-20T07:55:17.5299234Z, 存储结果:存储物理地址: rntbd://cdb-ms-prod-northeurope1-fd25.documents.azure.com:14307/apps/2268c937-d7b4-449e-9d76-a2d50d5d3546/services/df84607d-8553-4938-aa0d-913563078a93/partitions/b3701- ab2c-4a88-bb51-0ae729299a7e/replicas/132314907336368334p/, LSN:400340,GlobalCommittedLsn:400339,PartitionKeyRangeId:, IsValid:True,StatusCode:429,SubStatusCode:3200,RequestCharge: 0.38, ItemLSN: -1, SessionToken: , UsingLocalLSN: False, TransportException: null, ResourceType: StoredProcedure, 操作类型:ExecuteJavaScript\r\n,SDK: Microsoft.Azure.Documents.Common/2.11.0"},"headers":{"access-control-allow-credentials":"true","access-control-allow-origin":"https://cosmos.azure.com","内容类型":"application/json","lsn":"400340","strict-transport-security":"max-age=31536000","x-ms-activity-id":"cc616784-03ee- 4b10-9481-d62c26e496e4","x-ms-cosmos-llsn":"400340","x-ms-cosmos-quorum-acked-llsn":"400340","x-ms-current-replica-set-大小":"4","x-ms-current-write-quorum":"3","x-ms-gatewayversion":"version=2.11.0","x-ms-global-committed-lsn" :"400339","x-ms-number-of-read-regions":"1","x-ms-quorum-acked-lsn":"400340","x-ms-request-charge":" 0.38","x-ms-retry-after-ms":"8538","x-ms-schemaversion":"1.9","x-ms-serviceversion":"version=2.11.0.0","x- ms-substatus":"3200","x-ms-transport-request-id":"120","x-ms-xp-role":"1","x-ms-throttle-retry-count" :5,"x-ms-throttle-retry-wait-time-ms":32087},"activityId":"cc616784-03ee-4b10-9481-d62c26e496e4","substatus":3200,"retryAfterInMs":8538}

我该如何解决这个问题?存储过程有问题吗?

【问题讨论】:

  • 你的 RU 设置是什么?如果它对于您尝试做的事情来说太低,您会看到节流。您会看到 8 秒的回退。这可能意味着您不断向 Cosmos DB 发送请求(查询和删除的某种组合),这导致您的退避时间不断增长(并且增长超过了存储过程的 5 秒执行时间)。
  • @DavidMakogon 吞吐量 RU 设置为 1000

标签: azure azure-cosmosdb azure-cosmosdb-sqlapi


【解决方案1】:

当当前聚合 RU + 查询的 RU 超过您设置的阈值时,CosmosDB 将返回 429。例如,如果您的阈值是 400,并且到目前为止您已经使用了 380 RU,并且下一次查询需要 22 RU 才能完成,那么 cosmos 将拒绝代码为 429 的查询。如果下一次查询只需要 3 RU,它将成功。 1 秒后,累计 RU 值清零,22 RU 查询成功。

如果您收到 429,您还将收到一个“x-ms-retry-after-ms”标头,其中包含一个数字。在重试查询之前,您应该等待该毫秒数。

https://docs.microsoft.com/en-us/rest/api/cosmos-db/common-cosmosdb-rest-response-headers

或者,您可以通过提高阈值来避免 429(这也会增加服务成本)。因此,您必须决定是要重试还是提高阈值。这取决于您的应用程序的性质。

RU 或资源单位由 CosmosDB 服务根据服务需要完成的工作量来计算。它是您的索引有多大、正在传输多少数据、您使用多少 CPU、磁盘、内存等的组合... 为 RU 收费是 Cosmos 了解您将要运行的工作负载的一种方式,并且根据需要进行必要的后端更改。 cosmos 的每秒成本取决于您的 RU 阈值设置。它还允许 cosmos 在后端进行必要的更改以适应您的性能需求。如果您在全球不同地区进行读写,则 RU 计算会变得更加复杂。

您可以通过重组索引中的数据来降低查询的 RU 成本。如果您要分散到多个分区,则查询将并行运行,从而在更短的时间内完成更多工作。如果您减少或增加在网络、内存和 cpu 组件中移动的千字节,它也会改变 RU。

【讨论】:

    【解决方案2】:

    429错误是请求过多引起的,不是你的存储过程错误。

    但存储过程最适合写入繁重的操作,而不是读取或删除繁重的操作。相反,您可以使用 Bulk Executor Lib SDK,有 BulkDelete 功能。

    这里是document

    【讨论】:

    • 我认为将存储过程分类为专门针对写入繁重的操作是不公平的。也不确定您为什么要推荐一种与问题无关的替代方法。我们甚至对 OP 的查询或被删除的文档数量一无所知。根据错误输出,我们所知道的是有超过 8 秒的回退,这意味着它们可能会用请求淹没 Cosmos DB 并超出分配的 RU。
    【解决方案3】:

    最简单的方法是增加 azure 门户中的吞吐量,取决于您执行此类操作的频率,您可以增加吞吐量并执行您的操作并重置它 - 如果它是一次性的 - 或找到您的最佳吞吐量。您应该四处寻找数字,但如果是一次尝试,请尝试 1000 并在每次尝试时乘以 10 直到它起作用,并且不要忘记将值重置回原来的值,否则您会收到一大笔账单:)
    (如果您的吞吐量设置为更多或大约 4000 并获得一些成本优势,您也可以考虑自动扩展它)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多