azure-cosmosdb - 如何在 Cosmos Db 中同步相关集合?
问题描述
我的应用程序需要支持按发票 ID 和客户查找发票。出于这个原因,我创建了两个集合,在其中存储(完全相同)相同的发票文档:
InvoicesById
, 带分区键/InvoiceId
InvoicesByCustomerId
, 带分区键/CustomerId
显然你应该在查询时使用分区键,因为有两个查询我需要两个集合。我想未来可能会有更多。
更新主要是对InvoicesById
集合进行的,但是我还需要将更改复制到InvoicesByCustomer
(和其他)。
是否有任何最佳实践或理智的方法来保持集合同步?
我在想改变提要什么的。我想避免编写此同步代码并避免由于集合之间缺少事务(等)而导致不一致的风险。或者,也许我在这里遗漏了一些重要的东西。
解决方案
更改提要可以解决问题,尽管我建议在暴力破解问题之前退后一步。
请在此处找到描述拆分问题的详细文章:Azure Cosmos DB。分区。
根据 Microsoft 对可维护数据增长的建议,您应该选择具有最高基数的分区键(在您的情况下,我假设它会是InvoiceId
)。主要原因是:
将请求单元 (RU) 消耗和数据存储均匀地分布在所有逻辑分区中。这可确保跨物理分区的 RU 消耗和存储分布均匀。
您不需要使用CustomerId
分区键创建单独的容器,因为它不会为您提供所需的,最重要的是,未来可维护的性能,并且当太多发票链接到同一客户时,可能会导致物理分区数据倾斜。
为了获得最佳和可扩展的查询性能,您很可能需要(以及将来InvoiceId
的其他人)作为分区键和索引策略。CustomerId
当您查询的数据分布在多个物理分区 (PP) 之间时,消耗中会有轻微的 RU 开销(绝对不是 RU 的倍增,而是每个请求的额外 RU),但与数据时发生的问题相比,它可以忽略不计开始超过 50、100、150GB。
为什么CustomerId
可能不是预期增长超过 50GB 的数据集的最佳分区键?
主要原因是 Cosmos DB 旨在水平扩展,并且每个 PP 的预置吞吐量仅限于[total provisioned per container (or DB)] / [number of PP]
.
一旦由于超过 50GB 大小而发生 PP 拆分,现有 PP 以及两个新创建的 PP 的最大吞吐量将低于拆分前的吞吐量。
因此,想象以下场景(将天数视为操作之间时间的度量):
- 您已经创建了具有预置 10k RU 和
CustomerId
分区键的容器(这将生成一个底层 PP1)。每个 PP 的最大吞吐量为10k/1 = 10k RUs
- 逐渐将数据添加到容器中,您最终会得到 3 个大客户的 C1[10GB]、C2[20GB] 和 C3[10GB] 发票
- 当另一个客户使用 C4[15GB] 数据加入系统时,Cosmos DB 必须将 PP1 数据拆分为两个新创建的 PP2 (30GB) 和 PP3 (25GB)。每个 PP 的最大吞吐量为
10k/2 = 5k RUs
- 另外两个客户 C5[10GB] C6[15GB] 被添加到系统中,并且都以 PP2 结束,这导致另一个分裂 -> PP4 (20GB) 和 PP5 (35GB)。现在每个 PP 的最大吞吐量是
10k/3 = 3.333k RUs
重要提示:因此,
[Day 2]
C1
查询的数据最多有 10k RU,但[Day 4]
最多只有 3.333k RU,这直接影响查询的执行时间
这是在当前版本的 Cosmos DB (12.03.21) 中设计分区键时要记住的主要事项。
推荐阅读
- sql - 选择仅订购特定会议而不订购其他会议的客户
- python - 如何在运行 Django 3.0.3 的开发服务器时覆盖默认的 http 连接超时?
- android - Flutter 运行错误 - 任务“:app:processDebugResources”执行失败
- three.js - 关于 bufferGeometry 需求更新
- python - 当值更改python时动态提交表单
- html - R Shiny 使用 SB Admin 2 中的 Html 模板 - 仪表板
- d3.js - d3.js 附加圆圈时缺少第一个索引
- python-3.x - 在 Visual Studio Code 上的 Python 中创建 Azure 函数以触发队列
- c# - 在进行选择的选定行上更改 DataGridView 中的值
- bash - 将 info.plist 中的版本替换为 Azure 管道的 bash 脚本