我正在使用以下存储过程从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}
如何解决此问题?存储过程有问题吗?
答案 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)