首页 文章

DocumentDB PartitionKey和性能

提问于
浏览
5

我有一个场景,我存储大量的第三方数据,供业务用户进行临时分析 . 使用多个自连接,投影和范围,大多数针对数据的查询都会很复杂 .

在选择 PartitionKey 以便在Azure DocumentDB中使用时,我看到人们建议使用逻辑分隔符,如TenantId,DeviceId等 .

然而,鉴于DocumentDB的并行特性,我很好奇它如何处理基于某种GUID或大整数的 PartitionKey ,这样在大型读取期间,它将是高度分辨的 .

考虑到这一点,我设计了一个包含两个集合的测试:

  • test-col-1

  • PartitionKey 是TenantId,大约有100个可能的值

  • test-col-2

  • PartitionKey 是第三方分配的唯一值,其格式为"AB1234568" . 保证第三方在全球范围内独一无二 .

两个集合都设置为100,000 RU .

在我的实验中,我加载了大约2,000个文档的集合 . 每个文档大小约为20 KB,并且高度非规范化 . 每个文档都是一个订单,其中包含多个作业,每个作业都包含用户,价格等 .

示例查询:

SELECT
orders.Attributes.OrderNumber,
orders.Attributes.OpenedStamp,
jobs.SubOrderNumber,
jobs.LaborTotal.Amount As LaborTotal,
jobs.LaborActualHours As LaborHours,
jobs.PartsTotal.Amount As PartsTotal,
jobs.JobNumber,
jobs.Tech.Number As TechNumber,
orders.Attributes.OrderPerson.Number As OrderPersonNumber,
jobs.Status
FROM orders
JOIN jobs IN orders.Attributes.Jobs
JOIN tech IN jobs.Techs
WHERE   orders.TenantId = @TentantId
    AND orders.Attributes.Type = 1
    AND orders.Attributes.Status IN (4, 5)";

在我的测试中,我调整了以下设置:

  • 默认 ConnectionPolicy

  • Best practices ConnectionPolicy

  • ConnectionMode.DirectProtocol.Tcp

  • 各种 MaxDegreeOfParallelism

  • 各种 MaxBufferedItemCount

使用 EnableCrossPartitionQuery = true 查询带有GUID PartitionKey的集合 . 我正在使用C#和.NET SDK v1.14.0 .

在我使用默认设置进行的初始测试中,我发现使用 TentantId 作为PartitionKey查询集合的速度更快,与GUID-keyed集合上的 4,680 ms 相比,它平均为 3,765 ms .

当我使用 TCPConnectionPolicy 设置为 Direct 时,我发现 TenantID 集合查询时间减少了近1000毫秒,平均为 2,865 ms ,而GUID集合增加了大约800毫秒,平均为 5,492 ms .

当我开始玩 MaxDegreeOfParellelismMaxBufferedItemCount 时,事情开始变得有趣 . TentantID 集合查询时间通常不受影响,因为查询不是交叉集合,但GUID集合显着加速,达到的值与 450 msMaxDegreeOfParellelism = 2000, MaxBufferedItemCount = 2000)一样快 .


鉴于这些观察, why would you not want to make the PartitionKey as broad a value as possible

1 回答

  • 3

    当我开始玩MaxDegreeOfParellelism和MaxBufferedItemCount时,事情开始变得有趣 . TentantID集合查询时间通常不受影响,因为查询不是交叉收集,但GUID集合显着加速,达到450毫秒的值(MaxDegreeOfParellelism = 2000,MaxBufferedItemCount = 2000) .

    MaxDegreeOfParallelism可以设置ParallelOptions实例启用的最大并发任务数 . 据我所知,这是一个客户端并行性,它会占用您站点上的CPU /内存资源 .

    鉴于这些观察,为什么你不想让PartitionKey尽可能广泛?

    对于写入操作,我们可以跨分区键进行扩展,以便使用您已配置的全部内容 . 对于读取操作,我们需要最小化跨分区查找以降低延迟 .

    此外,正如这份官方文件所述:

    分区键的选择是您在设计时必须做出的重要决定 . 您必须选择具有多种值且具有访问模式的属性名称 . 最佳做法是使分区键具有许多不同的值(至少100s-1000s) . 要实现容器的完整吞吐量,必须选择允许您在一些不同的分区键值之间均匀分布请求的分区键 .

    有关更多详细信息,请参阅How to partition and scale in Azure Cosmos DB和此 Channels 9教程有关Azure DocumentDB Elastic Scale - Partitioning .

相关问题