gpt4 book ai didi

c# - CosmosDb 使用 insertMany 请求率很大

转载 作者:行者123 更新时间:2023-12-03 04:44:40 25 4
gpt4 key购买 nike

我有以下存储库类,可将数据批量插入到 CosmosDb 数据库中:

public bool InsertZonierData(List<Zonier> zonierList)
{
if (zonierList == null || !zonierList.Any())
{
throw new ZonierListNullOrEmptyException();
}
else
{
try
{
_collection.InsertMany(zonierList);
return true;
}
catch (MongoBulkWriteException ex)
{
throw new DataBaseWritingException(ex.Message, ExceptionCodeConstants.DataBaseWritingExceptionCode);
}
}
}

不幸的是,zonierList 中的元素超过 30000 个,它在 CosmosDb 上抛出以下异常:

Unhandled Exception: MongoDB.Driver.MongoCommandException: Command insert failed: Message: {"Errors":["Request rate is large"]}

根据文档,这是与 Cosmos 上的 RU/秒相关的问题。当然,一个简单的方法是增加它,但这不是我想要做的。

是否有一种简单明了的方法来重构该方法,使我们能够在不破坏 CosmosDb 400 RU/秒的情况下插入数据。

最佳答案

Mongo 驱动程序会告诉您哪些记录出现错误以及哪些记录根本没有被处理。如果所有错误(通常是一个)的代码为 16500,那么您的问题是限制并重试错误,并且剩余记录是安全的。否则你的错误是由其他原因引起的,你应该进行分析并决定是否继续重试。

Mongo 驱动程序不返回 HTTP header ,而 Cosmos DB 建议在重试之前延迟,但这不是什么大问题。无论如何,延迟并不能保证成功,因为命中同一数据库的其他请求可能会耗尽 RU。您最好尝试并确定自己的重试规则。下面是简单的递归解决方案,它不断重试,直到一切顺利或达到重试限制。

    private async Task InsertManyWithRetry(IMongoCollection<BsonDocument> collection, 
IEnumerable<BsonDocument> batch, int retries = 10, int delay = 300)
{
var batchArray = batch.ToArray();

try
{
await collection.InsertManyAsync(batchArray);
}
catch (MongoBulkWriteException<BsonDocument> e)
{
if (retries <= 0)
throw;

//Check if there were any errors other than throttling.
var realErrors = e.WriteErrors.Where(we => we.Code != 16500).ToArray();
//Re-throw original exception for now.
//TODO: We can make it more sophisticated by continuing with unprocessed records and collecting all errors from all retries.
if (realErrors.Any())
throw;

//Take all records that had errors.
var errors = e.WriteErrors.Select(we => batchArray[we.Index]);
//Take all unprocessed records.
var unprocessed = e.UnprocessedRequests
.Where(ur => ur.ModelType == WriteModelType.InsertOne)
.OfType<InsertOneModel<BsonDocument>>()
.Select(ur => ur.Document);

var retryBatchArray = errors.Union(unprocessed).ToArray();

_logger($"Retry {retryBatchArray.Length} records after {delay} ms");

await Task.Delay(delay);

await InsertManyWithRetry(collection, retryBatchArray, retries - 1, delay);
}
}

关于c# - CosmosDb 使用 insertMany 请求率很大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55263897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com