当前位置: 首页 > 知识库问答 >
问题:

使用. NET Core SDK 3.5从CosmosDB检索文档时的OutOfMemoryException

丌官信厚
2023-03-14

我有一个带有单个endpoint的API,它从CosmosDB集合中检索文档。endpoint在常见场景下工作良好。然而,当我在API上执行压力测试,以测量它在重负载下如何响应时,我在站点上经历了中断(站点开始用502 - bad网关响应请求)。

在Application Insights上搜索时,我注意到在执行句子以从CosmosDB集合中检索文档时引发了OutOfMemory异常。我用来读取文档的方法是ReadNextAsync,日志特别指向这一行。

我们阅读并测试了Cosmos DB留档提到的最佳实践和提示,以从我们这边丢弃SDK的不良使用,但即使尝试使用不同的配置(MaxItemCount、MaxBufferedItems、MaxConcurrency),问题仍然存在。

在执行了几个测试后,我注意到如果我限制要从集合中检索的文档量(例如使用TOP 40子句),则不会显示异常或站点中断。相反,所有请求都使用200状态代码成功处理。由于我在我们的全FWK API上没有遇到此类问题,它具有与完全相同的逻辑。这里描述的NET Core API,我想知道我是否会对. NET Core SDK使用不当。

为了分享更多的上下文,我在下面详细描述了通用规范,以及我如何配置CosmosDB的细节,以及检索文档的实现。此外,我在Application Insights exceptions表中添加了日志和相关的堆栈跟踪。

通用规格

    < li>API。NET CORE 2.2 < li >微软。Azure.Cosmos 3.5.0

Cosmos DB规格

    < li>CosmosDB客户端连接 < ul > < li >连接模式:直接 < li >申请地区:美国西部 < li >其余的默认值
  • ~600个文件
  • ~30K每个文档的大小
  • 分区键-

压力情景详细信息

每秒执行 400 个请求,每个请求最多检索 200 个文档。

文档检索实现

var feed = container.GetItemLinqQueryable<T>(false, null, queryRequestOptions).Where(predicate).ToFeedIterator();
var batches = new List<FeedResponse<T>>();

while (feed.HasMoreResults)
{
    var batch = await feed.ReadNextAsync();
    batches.Add(batch);
}

应用洞察异常堆栈跟踪

Response status code does not indicate success: 500 Substatus: 0 Reason: (System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.AddWithResize(T item)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParsePropertyNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseArrayNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParsePropertyNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.Parse(IJsonReader jsonTextReader)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator..ctor(ReadOnlyMemory`1 buffer, Boolean skipValidation)
   at Microsoft.Azure.Cosmos.Json.JsonNavigator.Create(ReadOnlyMemory`1 buffer, JsonStringDictionary jsonStringDictionary, Boolean skipValidation)
   at Microsoft.Azure.Cosmos.CosmosElements.CosmosElementSerializer.ToCosmosElements(MemoryStream memoryStream, ResourceType resourceType, CosmosSerializationFormatOptions cosmosSerializationOptions)
   at Microsoft.Azure.Cosmos.CosmosQueryClientCore.GetCosmosElementResponse(QueryRequestOptions requestOptions, ResourceType resourceType, ResponseMessage cosmosResponseMessage, PartitionKeyRangeIdentity partitionKeyRangeIdentity, SchedulingStopwatch schedulingStopwatch)
   at Microsoft.Azure.Cosmos.CosmosQueryClientCore.ExecuteItemQueryAsync[RequestOptionType](Uri resourceUri, ResourceType resourceType, OperationType operationType, RequestOptionType requestOptions, SqlQuerySpec sqlQuerySpec, String continuationToken, PartitionKeyRangeIdentity partitionKeyRange, Boolean isContinuationExpected, Int32 pageSize, SchedulingStopwatch schedulingStopwatch, CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.ItemProducer.BufferMoreDocumentsAsync(CancellationToken token)
   at Microsoft.Azure.Cosmos.Query.ItemProducer.BufferMoreIfEmptyAsync(CancellationToken token)
   at Microsoft.Azure.Cosmos.Query.ItemProducer.TryMoveNextPageAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.ItemProducerTree.TryMoveNextPageImplementationAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.ItemProducerTree.ExecuteWithSplitProofingAsync(Func`2 function, Boolean functionNeedsBeReexecuted, CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.ItemProducerTree.TryMoveNextPageAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.CosmosParallelItemQueryExecutionContext.DrainAsync(Int32 maxElements, CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.PipelinedDocumentQueryExecutionContext.ExecuteNextAsync(CancellationToken token)
   at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.LazyCosmosQueryExecutionContext.ExecuteNextAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.CosmosQueryExecutionContextWithNameCacheStaleRetry.ExecuteNextAsync(CancellationToken cancellationToken)
   at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.CatchAllCosmosQueryExecutionContext.ExecuteNextAsync(CancellationToken cancellationToken)).
{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.ResponseMessage.EnsureSuccessStatusCode","level":0,"line":0}

{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.CosmosResponseFactory.CreateQueryFeedResponseHelper","level":1,"line":0}

{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.CosmosResponseFactory.CreateQueryFeedResponse","level":2,"line":0}

{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.FeedIteratorCore`1+<ReadNextAsync>d__5.MoveNext","level":3,"line":0}

共有1个答案

禄烨然
2023-03-14

我没有使用cosmosdb,所以不确定这是否真的相关,但根据azure文档,每个请求限制为4MB。

我是否正确认为在上面给出的示例代码中没有过滤?是否意味着返回了所有 600 个文档(每个文档约 30k 个)?

尝试将其拆分为多个请求可能会更成功

 类似资料:
  • 我已经创建了一个azure函数,当一个新文档被添加到一个集合中时,它会被触发。 是否可以从该集合中选择特定文档,然后查询所选文档中的数据? 例如,在所谓的募集服装,我有一个文件,有一个ID: 12345Tops.我想查询ID为:12345Tops的文档中找到的数据。 或者检索集合中的第一个文档,然后查询第一个选定文档 我看过带有http触发器的azure函数:https://docs.micros

  • 本文向大家介绍使用Java从MongoDB检索数据时如何跳过文档?,包括了使用Java从MongoDB检索数据时如何跳过文档?的使用技巧和注意事项,需要的朋友参考一下 从MongoDB集合中检索记录时,可以使用skip()方法跳过结果中的记录。 句法 Java MongoDB库提供了一个具有相同名称的方法,以跳过记录,并绕过表示要跳过的记录数的整数值来调用此方法(基于find()方法的结果)。 示

  • 我知道如何使用Azure云函数在我的CosmosDB实例中创建、读取和更新文档,但仍然不知道如何实现删除。我用作参考的主要文档是https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-cosmos-db-triggered-function. 我尝试使用没有id的输入和输出绑定(从而获取整个集合),然后过滤要从

  • 使用JestClient从ElasticSearch检索文档,获取Double值而不是整数。 我正在使用JestClient(在java中)获取字段值,我希望makeId和yearId的值为integer,但值返回为Double, Jest maven Depandency- {“take”:29,“timed_out”:false,“_shards”:{“total”:5,“successed”

  • 问题内容: 尝试访问我的ElasticSearch文档中的分析/标记化的文本。 我知道您可以使用Analyze API根据您的分析模块来分析任意文本。因此,我可以将文档中的数据复制并粘贴到Analyze API中,以查看如何对它们进行标记。 但是,这似乎不必要地耗时。有什么方法可以指示ElasticSearch在搜索结果中返回标记化文本?我已经浏览了文档,却没有发现任何东西。 问题答案: 看看另一

  • 是否可以将在集群节点上运行的服务注册为观察者,以便在th集群中跨多个cosmos db帐户为文档集合更改提要? https://docs.microsoft.com/en-us/azure/cosmos-db/serverless-computing-database 如何通过changefeed处理器库触发服务APIendpoint?或者,如何将集群节点上运行的服务注册为观察者,以便跨集群中的多