【问题标题】:Cosmos DB: Query documents by time interval using partition keyCosmos DB:使用分区键按时间间隔查询文档
【发布时间】:2020-02-27 12:08:48
【问题描述】:

如何选择分区键,以便在给定时间段内有效地查询我的所有文档?

背景:

我正在使用 Azure CosmosDB 为聊天应用程序构建分析工具。我有一个单独的容器来存储传入和传出的消息。典型的Message 文档如下所示:

{
    "version": "v1",
    "partition_key": "user_id",
    "timestamp": "2020-01-30 14:02:32.402+00:00",
    "type": "incoming_message",
    "message": "hi there",
    "sender": "sender_id",
    "receiver": "receiver_id",
}

我已考虑将以下选项作为我的分区键:

  1. User id:使用这种方法,我可以轻松地按用户查询所有消息。但是,基于时间的过滤必须是跨分区查询,并且 RU 成本会很高,尤其是在容器中有数千个文档的情况下。
  2. 日期特定值:根据this,我可以使用日期和随机数作为分区键(例如:2018-08-09.1、2018-08-09.2 等) .但是,使用这种方法,我将不得不将数百个分区键传递到 in 子句 以便运行大时间间隔的查询(例如:过去 6 个月)。

对于选择更好的分区键以支持按时间过滤文档的单分区查询,您有什么建议吗?

【问题讨论】:

  • 时间戳是查询中唯一的过滤器吗?此查询中是否没有其他值将使用?
  • 嗨@MarkBrown,我还有其他疑问(例如:获取特定用户的所有消息)。对于其他查询,我将重复的消息文档存储在由用户 ID 分区的不同容器中。

标签: sql azure-cosmosdb partitioning database-partitioning azure-cosmosdb-sqlapi


【解决方案1】:

由于效率、性能和存储三个原因,日期对于分区数据存储中的分区键通常是一个糟糕的选择。

在写入繁重的工作负载中,当前日期始终是热分区。这意味着您将只使用您提供的任何吞吐量的一小部分。这效率不高,因为您将拥有从未使用过的吞吐量。它也不是高性能的,因为您将永远无法使用您提供的所有吞吐量。在某些情况下,这可能会起作用。但通常它们很小,而且总是很小。但是,一般来说,您总是希望避免使用永远无法扩展的分区策略,而这将不会。

要回答的第二个问题是每个逻辑分区的数据量,以确定该分区键值的粒度,以时间表示。如果您每天有 20GB 的数据,那么使用一天或更长的时间(周、月、年等)将永远无法工作。

要回答的第三个问题是您希望执行哪些聚合以及您尝试在查询中处理多少数据。 Cosmos DB 不是分析数据存储。它是基于行的 JSON 存储,最适合用作计算批处理或实时视图的主数据存储和服务层。从您的问题看来,您似乎正在寻找进行分析,因此您可能会受益于 ETL 将此数据放入列存储并在那里进行聚合。然后,您可以将聚合写回 Cosmos 并从那里提供服务。本文描述了我正在描述的lambda architecture。我并不是说你必须使用 Spark 作为其中的一部分。但是,如果您尝试对跨分区的大型数据集进行分析和聚合,则需要批处理层和分析计算平台来完成。

希望这有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 2022-11-12
    相关资源
    最近更新 更多