Azure Cosmos DB-'请求率很高。删除项目时可能需要更多请求单位”错误

时间:2020-05-20 08:02:18

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

我正在使用以下存储过程从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 通知:{“代码”:429,“正文”:{“代码”:“ 429”,“消息”:“消息: {\“错误\”:[\“请求率很大。可能会有更多请求单位 需要,因此未进行任何更改。请稍后重试此请求。 了解更多: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 / replicas / 132314907336368334p /, 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, StoreResult:StorePhysicalAddress: rntbd://cdb-ms-prod-northeurope1-fd25.documents.azure.com:14307 / apps / 2268c937-d7b4-449e-9d76-a2d50d5d3546 / services / df84607d-8553-4938-aa0d-913563078a93 / partitions / b37017a9- ab2c-4a88-bb51-0ae729299a7e / replicas / 132314907336368334334p /, LSN:400340,GlobalCommittedLsn:400339,PartitionKeyRangeId :, IsValid:True,StatusCode:429,SubStatusCode:3200,RequestCharge: 0.38,ItemLSN:-1,SessionToken:,usingLocalLSN:False,TransportException:null,ResourceType:StoredProcedure, OperationType:ExecuteJavaScript \ r \ n,SDK: Microsoft.Azure.Documents.Common / 2.11.0“},”标题“:{” access-control-allow-credentials“:” true“,” access-control-allow-origin“:” https://cosmos.azure.com“ ,“内容类型”:“ application / json”,“ lsn”:“ 400340”,“严格传输安全”:“ 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-size“:” 4“,” x-ms-current-write-quorum“:” 3“,” x-ms-gatewayversion“:” version = 2.11.0“,” x-ms-global-committed- lsn“:” 400339“,” x-ms读取区域数“:” 1“,” x-ms-仲裁数量-lsn“:” 400340“,” x-ms-请求费用“ :“ 0.38”,“ x-ms-重试后-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}

如何解决此问题?存储过程有问题吗?

3 个答案:

答案 0 :(得分:1)

429错误是由太多请求引起的,并非您的存储过程错误。

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

这里是document

答案 1 :(得分: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了解您将要运行的工作负载的一种方式,根据需要进行必要的后端更改。波斯菊的每秒成本基于您的RU阈值设置。它还允许波斯菊在后端进行必要的更改以适应您的性能需求。如果您是从全球不同地区进行读写,则RU计算将变得更加复杂。

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

答案 2 :(得分:0)

最简单的方法是增加azure门户中的吞吐量,具体取决于您执行该操作的频率,您可以增加吞吐量并执行并重置操作-如果它是关闭的或者发现您的操作最佳吞吐量。您应该四处寻找该数字,但是如果选择不正确,则尝试使用类似1000的值,然后每次尝试乘以10直到成功,并且不要忘记将值重置为原来的值,否则您将得到大笔账单:)
enter image description here (如果您的吞吐量设置为大于或等于4000并获得一定的成本优势,您也可以考虑自动缩放比例)