如何解决从 Azure Function 向 Azure Cosmos 缓慢插入的问题

How to troubleshoot slow inserts to Azure Cosmos from Azure Function

我想使用 Cosmos .NET SDK v3 将小文档(<10 JSON 个字段)从 Azure Function 插入到 Azure Cosmos DB,但每次插入需要 1-2 秒。

插入代码为

await container.CreateItemAsync(
                    objectToAdd,
                    new PartitionKey(objectToAdd.PartitionKey),
                    new ItemRequestOptions { EnableContentResponseOnWrite = false })

查看诊断,大部分时间是在项目流式传输期间花费的(请参阅末尾的日志)。

Azure Functions和Cosmos都部署在同一个区域(北欧)。 Cosmos 允许通过启用 vnet 的服务端点访问 Azure Functions。

我已通读 https://blog.tdwright.co.uk/2019/06/29/aggressively-tuning-cosmos-db-the-long-way-round/ and https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips-dotnet-sdk-v3-sql 尝试了以下内容:

我没试过:

对于应该完全在单个数据中心内的东西来说,这似乎是一个很长的响应时间。

我的问题:

{
    "Summary": {
        "StartUtc": "2020-10-22T21:21:03.3520979Z",
        "ElapsedTime": "00:00:01.0030109",
        "UserAgent": "cosmos-netstandard-sdk/3.6.0|3.4.2|38128|X86|Microsoft Windows 10.0.14393 |.NET Core 4.6.29215.02|"
    },
    "Context": [
        {
            "Id": "ItemStream",
            "ElapsedTime": "00:00:01.0030109"
        },
        {
            "Id": "ItemSerialize",
            "ElapsedTime": "00:00:00.0000212"
        },
        {
            "Id": "ExtractPkValue",
            "ElapsedTime": "00:00:00.0000402"
        },
        {
            "Id": "BatchAsyncContainerExecutor.Limiter",
            "ElapsedTime": "00:00:00.0000056"
        },
        {
            "Id": "RequestInvokerHandler",
            "ElapsedTime": "00:00:00.0071549"
        },
        {
            "Id": "Microsoft.Azure.Cosmos.Handlers.RetryHandler",
            "ElapsedTime": "00:00:00.0071272"
        },
        {
            "Id": "Microsoft.Azure.Cosmos.Handlers.RouterHandler",
            "ElapsedTime": "00:00:00.0070979"
        },
        {
            "Id": "TransportHandler",
            "ElapsedTime": "00:00:00.0070954"
        },
        {
            "Id": "PointOperationStatistics",
            "ActivityId": "...",
            "StatusCode": 200,
            "SubStatusCode": 0,
            "RequestCharge": 7.62,
            "RequestUri": "...",
            "RequestSessionToken": null,
            "ResponseSessionToken": "..",
            "ClientRequestStats": {
                "RequestStartTimeUtc": "2020-10-22T21:21:04.3479626Z",
                "RequestEndTimeUtc": "2020-10-22T21:21:04.3548940Z",
                "RequestLatency": "00:00:00.0069314",
                "IsCpuOverloaded": false,
                "NumberRegionsAttempted": 1,
                "ResponseStatisticsList": [
                    {
                        "ResponseTime": "2020-10-22T21:21:04.354894Z",
                        "ResourceType": 2,
                        "OperationType": 40,
                        "StoreResult": "StorePhysicalAddress: rntbd://cdb-ms-prod-northeurope1-fd8.documents.azure.com:14173/apps/.../, LSN: 304, GlobalCommittedLsn: 303, PartitionKeyRangeId: 0, IsValid: True, StatusCode: 200, SubStatusCode: 0, RequestCharge: 7.62, ItemLSN: -1, SessionToken: ..., UsingLocalLSN: False, TransportException: null"
                    }
                ],
                "AddressResolutionStatistics": [],
                "SupplementalResponseStatistics": [],
                "FailedReplicas": [],
                "RegionsContacted": [
                    "<redacted>"
                ],
                "ContactedReplicas": [
                    "rntbd://cdb-ms-prod-northeurope1-fd8.documents.azure.com:14173/apps/<redacted>/",
                    "rntbd://cdb-ms-prod-northeurope1-fd8.documents.azure.com:14387/apps/<redacted>/",
                    "rntbd://cdb-ms-prod-northeurope1-fd8.documents.azure.com:14215/apps/<redacted>/",
                    "rntbd://cdb-ms-prod-northeurope1-fd8.documents.azure.com:14064/apps/<redacted>/"
                ]
            }
        },
        {
            "Id": "BatchAsyncContainerExecutor.ToResponse",
            "ElapsedTime": "00:00:00.0000295"
        }
    ]
}

您似乎在使用批量模式。请记住,批量模式是一种在发送大量操作时使 RU 饱和的模式。你提到你要发送 < 10,所以我建议(除非你有发送更多的情况)在这种情况下你不要使用批量模式。

另请检查:

  • 您使用的是 Singleton CosmosClient 吗?
  • 实例 运行 是否与您的写入 Cosmos DB 区域位于同一区域?
  • 更新您的 SDK,您使用的是 3.6.0 版,在 3.11.0 中对 Bulk(如果您仍想使用 Bulk)进行了改进,使其在文档数量较少的情况下速度更快。