You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Cosmos DB物理分区何时创建?性能问题求助

解答你的Cosmos DB物理分区与性能问题

先来说说物理分区为什么没有自动拆分的问题,再分析你遇到的性能退化原因,最后给你一些针对性的优化建议。

为什么只有一个物理分区?

Cosmos DB的物理分区拆分是基于两个核心阈值触发的:

  • 单个物理分区的存储容量达到50GB
  • 单个物理分区的吞吐量(RU/s)达到10,000 RU/s(固定RU模式下),或者自动缩放模式下达到容器最大RU的1/10

从你的Partition Stats结果来看,文档总大小才0.045GB,远低于50GB的存储阈值。另外你需要检查容器的吞吐量配置:如果是固定RU,比如配置了1000 RU/s,单个物理分区完全能承载这个量级的吞吐量,所以不会触发拆分。只有当你的数据存储或吞吐量需求突破上述阈值时,Cosmos才会自动拆分物理分区。

负载测试下性能退化的原因分析

虽然只有一个物理分区,但你的计数查询在压力下变慢,可能有以下几个原因:

  1. Count查询的固有开销:Cosmos DB没有维护原生的计数索引,CountAsync需要遍历分区内所有符合条件的文档来统计数量。当分区内文档增多、系统压力增大时,这个遍历的RU消耗会上升,导致延迟增加。
  2. 冗余的查询条件:你的查询里同时指定了PartitionKey = new PartitionKey(code.ToUpper())和e.Code.ToUpper() == code.ToUpper(),后者是完全冗余的——因为分区键已经限定了当前查询的范围是该code对应的分区,分区内所有文档的Code.ToUpper()必然等于指定的值,这个条件只会增加查询的过滤开销。
  3. RU资源不足或限流:如果容器配置的RU在负载测试时被耗尽,Cosmos会返回429限流错误,客户端会自动重试,这会显著增加查询耗时。你可以在门户的指标里查看Throttled Requests指标,确认是否存在限流。
  4. 资源竞争:负载测试时,其他请求也在占用该物理分区的RU资源,导致你的计数查询能分配到的RU减少,从而变慢。

针对性的优化建议

1. 优化计数查询的性能

  • 移除冗余条件:删除Where子句中的e.Code.ToUpper() == code.ToUpper(),简化查询逻辑:
    return await _docDbClient.CreateDocumentQuery<DigitalMembershipDeviceRegistrationItem>(
        UriFactory.CreateDocumentCollectionUri(_docDbDatabaseName, _docDbDigitalMembershipsCollectionName),
        queryOptions)
        .Where(e => e.CollectionType == DigitalMembershipCollectionTypes.RefreshItem)
        .CountAsync();
    
  • 预计算计数:维护一个单独的计数文档,比如在每个分区下存储一个PartitionCount文档,记录该分区内RefreshItem的数量。每次插入/删除RefreshItem时,通过事务(Cosmos DB的存储过程或批量操作)更新这个计数。查询时直接读取该文档,RU消耗极低,延迟稳定。
  • 检查索引策略:确保CollectionType字段被索引(默认自动索引所有字段,无需额外配置,但可以在门户中确认索引策略是否包含该字段)。

2. 调整容器吞吐量配置

  • 查看门户中的Request Units (RU) Usage指标,如果负载测试时RU使用率接近100%,说明需要增加固定RU配置,或者开启自动缩放RU,让Cosmos根据负载自动调整吞吐量。
  • 如果存在429限流错误,优先扩容RU或者调整自动缩放的最大RU值。

3. 关于物理分区的补充说明

当前你的数据量和吞吐量都没达到拆分阈值,所以单个物理分区是正常的。性能问题的根源不是物理分区数量,而是查询本身的开销和RU配置。当后续数据量增长到单个分区接近50GB,或者吞吐量超过10k RU/s时,Cosmos会自动拆分物理分区,无需手动干预。

另外,你选择5位会员码作为分区键,基数足够(数千个分区键),这种设计是合理的,后续数据增长后会自动均衡到多个物理分区。

4. 其他验证点

  • 确认客户端单例模式已正确实现(你已经提到,这很关键,避免重复创建客户端的开销)。
  • 检查查询的RU消耗:在FeedOptions中添加PopulateQuotaInfo = true,然后通过ResponseHeaders获取x-ms-request-charge值,了解该查询每次消耗的RU,判断是否有优化空间。

内容的提问来源于stack exchange,提问作者Khaled Hikmat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:40:18