Azure Cosmos DB - '请求率很大。删除项目时可能需要更多请求单位的错误
Posted
技术标签:
【中文标题】Azure Cosmos DB - \'请求率很大。删除项目时可能需要更多请求单位的错误【英文标题】: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 【参考方案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 并获得一些成本优势,您也可以考虑自动扩展它)
【讨论】:
以上是关于Azure Cosmos DB - '请求率很大。删除项目时可能需要更多请求单位的错误的主要内容,如果未能解决你的问题,请参考以下文章