首页 > 解决方案 > CosmosDb - 写入操作导致错误。错误=16500

问题描述

我在 CosmosDB 上有一个使用 MongoDB 的数据库。

这是我使用 Polly 的重试模式:

_retryPolicy = Policy
    .Handle<MongoCommandException>(e =>
    {
        if (e.Code != 16500 /*(RateLimitCode)*/ || !(e.Result is BsonDocument bsonDocument))
        {
            return false;
        }

        if (bsonDocument.TryGetValue("StatusCode", out var statusCode) && statusCode.IsInt32)
        {
            switch (statusCode.AsInt32)
            {
                case 429: //HttpThrottleErrorCode
                case 1: //HttpServiceIsUnavailable
                case 50: //HttpOperationExceededTimeLimit:
                    return true;
                default:
                    return false;
            }
        }

        return true;
    })
    .Or<MongoConnectionException>()
    .WaitAndRetryAsync(2, i => TimeSpan.FromSeconds(MongoRepositoryConstants.RETRY_POLICY_TIME_OUT_IN_SECOND));

这是用于UpdateMany在 C# 中使用 MongoDb 驱动程序执行的代码:

public async Task<bool> UpdateManyAsync(IEnumerable<JObject> listRelatedQuotes, DateTime datetime, string quoteStatus)
{
    var listQuoteNumber = new BsonArray(listRelatedQuotes.Select(quote => quote[StdJsonDataLabel.toto][StdJsonDataLabel.QUOTE_IDENTIFIER_LABEL].ToString()));
    FilterDefinition<BsonDocument> filter = Builders<BsonDocument>.Filter.In(StdJsonDataPath.toto, listQuoteNumber);

    var update = Builders<BsonDocument>.Update.Set(StdJsonDataPath.fooooo, datetime.ToString("o"));

    if (!string.IsNullOrEmpty(quoteStatus))
    {
        update = update.Set(StdJsonDataPath.foooo2, quoteStatus);
    }

    bool res = false;
    await _retryPolicy.ExecuteAsync(async () =>
    {
        var result = await _collection.UpdateManyAsync(filter, update).ConfigureAwait(false);
        res = (result.MatchedCount > 0);
    });
    return res;
}

不幸的是,我在 CosmosDb 上遇到了以下问题:

写入操作导致错误。Error=16500, RetryAfterMs=12, Details=' 批量写入操作导致一个或多个错误。错误=16500,RetryAfterMs=12,详细信息='
MongoDB.Driver.MongoBulkWriteException`1[[MongoDB.Bson.BsonDocument,MongoDB.Bson,版本=2.8.1.0,文化=中性,PublicKeyToken=null]]

按照文档,我知道 16500 错误代码是数据库上 RU/sec 的问题。但这是一个MongoBulkWriteException所以我想知道它是否由重试策略处理

按照文档,MongoBulkWriteException不继承自MongoCommandException. 那么您能否确认 Polly 重试策略不适用于这种情况?

编辑:在 Azure 上观看 CosmosDb 仪表板,看起来要UpdateMany花费很多 RU: 在此处输入图像描述

标签: c#mongodbazureazure-cosmosdbpolly

解决方案


我们目前正在为 MongoDB 用户的服务器端重试新功能运行私人预览版,我认为这将有利于您在这里所做的事情。

这是如何工作的,当遇到 429 时,我们将在返回给用户之前自动重试最多 60 秒的请求。我们的测试表明,这几乎可以解决客户在像您一样使用 MongoDB 客户端或使用 mongoimport 等工具进行批量摄取时遇到的所有问题。

如果您有兴趣参与此私人预览,请在我的 Twitter 个人资料 markjbrown 上 DM 给我,并提供您希望我们启用此功能的电子邮件地址和 Cosmos DB 帐户名称。

谢谢。


推荐阅读