.NET Azure Function App 使用 UpsertItemAsync 上传到 CosmosDB 速度非常慢,尤其是与 Python 的 CosmosClient 相比

Posted

技术标签:

【中文标题】.NET Azure Function App 使用 UpsertItemAsync 上传到 CosmosDB 速度非常慢,尤其是与 Python 的 CosmosClient 相比【英文标题】:.NET Azure Function App using UpsertItemAsync to upload to CosmosDB is dramatically slow, especially compared to Python's CosmosClient 【发布时间】:2021-07-19 21:10:00 【问题描述】:

我有一个在 Azure 上运行的 .NET Function App,它正在将数据上传到 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 上运行时。

如何解释这种性能上的巨大差异?函数应用是不是很慢?

【问题讨论】:

【参考方案1】:

您的问题是您正在启用批量模式 (.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)

    //...

如果您要执行单个操作,请禁用批量模式。

【讨论】:

如果我删除批量执行但我保持上传代码原样,你认为它会有所作为吗? (部署和测试需要一段时间) 肯定会的。

以上是关于.NET Azure Function App 使用 UpsertItemAsync 上传到 CosmosDB 速度非常慢,尤其是与 Python 的 CosmosClient 相比的主要内容,如果未能解决你的问题,请参考以下文章

.NET Azure Function App 使用 UpsertItemAsync 上传到 CosmosDB 速度非常慢,尤其是与 Python 的 CosmosClient 相比

Azure Function App 对 Webhook 的初始响应

发布后似乎没有触发 Azure Function App

从 Azure Function App 调用 Snowflake 过程

从 Azure Function App 访问带有防火墙的 Azure Blob 存储

Azure Blob Storage V2,来自 Azure Function App 的异常 API 调用,升级后