首页 > 解决方案 > 使用 CosmosDB 跨分区查询以进行批量操作的最有效方法

问题描述

我有一个跨分区查询,它依次返回每个分区的行,这是有道理的,所有分区 1 的结果,所有分区 2 的结果等等。

对于返回的每一行,我需要执行一个操作,可以是删除或更新。

有太多记录无法全部读取然后执行操作,因此我需要输入结果并同时执行操作。

我遇到的问题是我很快就用完了 RU,因为我的操作依次在每个分区上运行,并且单个分区分配了十分之一的 RU。

我可以PartitionKey在中指定 aFeedOptions但这对我没有帮助,因为我不知道密钥是什么。

我的查询看起来像

select r.* from r where r.deleted 

partition一个叫做的字段上container

想象一下我有以下物品

container|title    |deleted
jamjar   |jam      |true      <--- stored in partition 5
jar      |pickles  |true      <--- stored in partition 5
tin      |cookies  |true      <--- stored in partition 8
tub      |sweets   |true      <--- stored in partition 9

我做select r.title from r where r.deleted 我的查询将按以下顺序返回行

jam      <--- stored in partition 5
pickles  <--- stored in partition 5
cookies  <--- stored in partition 8
sweets   <--- stored in partition 9

我使用 anActionBlock来允许我启动 2 个线程以对返回的每一行执行我的操作,因此我继续工作,jam 然后pickles在执行操作时消耗来自分区 5 的 RU和cookiessweetsjampickles

我希望结果返回为:

jam      <--- stored in partition 5
cookies  <--- stored in partition 8
sweets   <--- stored in partition 9
pickles  <--- stored in partition 5

对于正常的 API 调用,我们总是知道container,这是批量和非常不频繁的删除的要求。

如果知道分区的数量并且可以将分区号提供给查询就可以了,我很乐意发出 10 个查询并将其视为 10 个单独的作业。

标签: azure-cosmosdb

解决方案


您需要设置MaxDegreeOfParallelismwhich 是的一部分FeedOptions

FeedOptions queryOptions = new FeedOptions
{
   EnableCrossPartitionQuery = true,
   MaxDegreeOfParallelism = 10,
};

它将为每个分区创建一个客户端线程,如果您检查 HTTP 标头,您可以看到发生了什么

x-ms-documentdb-query-enablecrosspartition: True
x-ms-documentdb-query-parallelizecrosspartitionquery: True
x-ms-documentdb-populatequerymetrics: False
x-ms-documentdb-partitionkeyrangeid: QQlvANNcKgA=,3

注意QQlvANNcKgA=,3你会看到其中的 10 个,从,0,9我怀疑第一部分是一些页面跟踪,第二部分是分区

请参阅文档并行查询执行

这是 Fiddler 中 3 个查询的时间线视图:

  • MaxDegreeOfParallelism = 10:较慢且不太并行,而线程和连接正在旋转(您可以在左侧列表中看到 5 次额外的 SSL 握手,以及在时间轴中设置的“绿色”的最后 5 个请求之前的间隙)。还有 2 个(出于某种原因)请求获取集合的 PK 范围
  • MaxDegreeOfParallelism = 10(再次):几乎最佳并行。PK 范围信息似乎是从先前的请求中缓存的,并在此处重用,而不会发出任何无关的请求。
  • MaxDegreeOfParallelism = 0: 完全顺序。
    有趣的是,这些请求没有指定x-ms-documentdb-partitionkeyrangeid标头。

使用 DocumentClient v2.x针对具有6 个物理分区的集合运行查询。

另请注意,每个查询都会触发 7 个请求,第一个是“查询计划请求”(不可并行化),而以下 6 个返回实际数据。

在此处输入图像描述


推荐阅读