使用 UpsertItemAsync 上传到 CosmosDB 的 .NET Azure Function App 速度非常慢,尤其是与 Python 的 CosmosClient 相比
.NET Azure Function App using UpsertItemAsync to upload to CosmosDB is dramatically slow, especially compared to Python's CosmosClient
我在 Azure 上有一个 .NET 函数应用程序 运行,它正在像这样将数据上传到 CosmosDB:
foreach (var message in messages)
{
try
{
await notificationsContainer.UpserItemAsync(message, message.NTID);
}
catch (Exception exception)
{
//...
}
}
UpsertItemAsync 是一个包装器:
public async Task<T> UpsertItemAsync(T document, string partitionKey)
{
ItemResponse<T> response = await _container.UpsertItemAsync<T>(document, new PartitionKey(partitionKey));
return response.Resource;
}
我正在对 6500 条消息进行测试。将 640(!) 条消息上传到数据库用了 16 分钟。同时,使用Python的CosmosClient,调用
container.create_item(message)
乘以 6500,需要 131 秒才能完成。
此外,Function App 运行 在 Azure 上,CosmosClient 设置为直连模式:
CosmosClient client = clientBuilder
.WithConnectionModeDirect()
.WithThrottlingRetryOptions(new TimeSpan(0, 0, 0, 0, config.MaxRetryWaitTimeInMilliSeconds), config.MaxRetryCount)
.WithBulkExecution(true)
.Build();
虽然 python 脚本在本地 VM 上 运行。
对这种性能上的巨大差异有何解释?函数应用程序是不是非常慢?
您的问题是您启用了批量模式 (.WithBulkExecution(true)
),但每个操作都执行 await
。
使用批量模式(参考 https://devblogs.microsoft.com/cosmosdb/introducing-bulk-support-in-the-net-sdk/)时,您需要创建这些操作而不是单独等待。类似于:
List<Task> operations = new List<Task>();
foreach (var message in messages)
{
operations.Add(notificationsContainer.UpserItemAsync(message, message.NTID));
}
try
{
await Task.WhenAll(operations);
}
catch(Exception ex)
{
//...
}
如果您要执行单个操作,要么禁用批量模式,要么禁用批量模式。
我在 Azure 上有一个 .NET 函数应用程序 运行,它正在像这样将数据上传到 CosmosDB:
foreach (var message in messages)
{
try
{
await notificationsContainer.UpserItemAsync(message, message.NTID);
}
catch (Exception exception)
{
//...
}
}
UpsertItemAsync 是一个包装器:
public async Task<T> UpsertItemAsync(T document, string partitionKey)
{
ItemResponse<T> response = await _container.UpsertItemAsync<T>(document, new PartitionKey(partitionKey));
return response.Resource;
}
我正在对 6500 条消息进行测试。将 640(!) 条消息上传到数据库用了 16 分钟。同时,使用Python的CosmosClient,调用
container.create_item(message)
乘以 6500,需要 131 秒才能完成。
此外,Function App 运行 在 Azure 上,CosmosClient 设置为直连模式:
CosmosClient client = clientBuilder
.WithConnectionModeDirect()
.WithThrottlingRetryOptions(new TimeSpan(0, 0, 0, 0, config.MaxRetryWaitTimeInMilliSeconds), config.MaxRetryCount)
.WithBulkExecution(true)
.Build();
虽然 python 脚本在本地 VM 上 运行。
对这种性能上的巨大差异有何解释?函数应用程序是不是非常慢?
您的问题是您启用了批量模式 (.WithBulkExecution(true)
),但每个操作都执行 await
。
使用批量模式(参考 https://devblogs.microsoft.com/cosmosdb/introducing-bulk-support-in-the-net-sdk/)时,您需要创建这些操作而不是单独等待。类似于:
List<Task> operations = new List<Task>();
foreach (var message in messages)
{
operations.Add(notificationsContainer.UpserItemAsync(message, message.NTID));
}
try
{
await Task.WhenAll(operations);
}
catch(Exception ex)
{
//...
}
如果您要执行单个操作,要么禁用批量模式,要么禁用批量模式。