【发布时间】:2020-09-19 04:17:37
【问题描述】:
我们希望在 Cosmos DB 中存储一组文档,其主键为 EventId。这些记录平均分布在多个客户中。随着新文档的添加,客户需要访问一部分客户的最新记录。文档是不可变的,需要无限期地存储。
我们应该如何设计我们的分区键和查询来避免客户端都碰到相同的分区和/或高 RU 使用率?
如果我们只使用CustomerId作为分区键,我们最终会超出逻辑分区的10GB限制,如果我们使用EventId,那么查询就会变得低效(会导致在跨分区查询中,以及我们希望避免的高 RU 使用率)。
另一个想法是将文档分组到块中。即 PartitionKey = int(EventId / PartitionSize)。这将导致所有客户端访问最新的分区,这可能会导致性能下降和节流。
如果我们使用 CustomerId 和 int(EventId / PartitionSize) 的组合 PartitionKey,那么我不清楚如何避免跨分区查询来检索正确的文档集。
编辑:
澄清几点:
- 客户端将通过指定
CustomerId的列表、他们收到的最后一个EventId以及要检索的最大记录数来访问事件。 - 因此,单独使用
EventId效果不佳,因为它会导致跨分区查询(即WHERE EventId > LastEventId)。 - 系统可能会以 15 分钟为增量每天写入大约 1GB。
- 很难知道读取量会是多少,但我猜可能适中,可能有几千个客户端定期轮询 API。
【问题讨论】:
-
通常你不能优化读写的分区。要么让它有利于读取,要么让它有利于写入。实现这两者的常用方法是通过更改源将集合复制到具有不同分区方案的另一个集合(甚至是不同类型的数据库)。
-
这将有助于提供有关您希望运行的最常见或性能关键查询和预期数量的一些详细信息。例如,如果您期望 80/20 读/写与 20/80 相比,最佳答案可能会有所不同。
-
@NoahStahl 我已经添加了一些关于预期数量的更多细节。
标签: azure azure-cosmosdb