文档菜单
文档首页
/
MongoDB 手册
/

关于时间序列数据

本页内容

  • 时间序列数据的属性
  • 比较时间序列集合与常规集合
  • 分桶的工作原理
  • metaField 如何影响分桶
  • 桶目录
  • 创建
  • 关闭
  • 删除

MongoDB 在内部通过根据时间序列集合中的共同metaField 值对文档进行分组来优化时间序列数据。选择一个有用的值可以显著优化存储密度和查询性能。更多信息,请参见metaFields.

时间序列数据具有一些属性,使其与其他数据格式区分开来

  • 文档按顺序到达,需要频繁进行插入操作来追加它们。

  • 更新操作很少,因为每个文档代表一个时间点。

  • 如果您的应用程序受益于拥有广泛的记录,则删除操作很少。

  • 数据按时间和标识符(如股票代码)索引,该标识符标识它所属的唯一时间序列。

  • 数据量很大,因为每个单独的时间序列都需要一个庞大且不断增长的大量文档。

为了考虑这些因素,MongoDB使用一种专门的列式格式,将每个时间序列的文档分组在一起。这有以下好处

  • 减少存储和索引大小

  • 提高查询效率

  • 减少读取操作的I/O

  • 增加对WiredTiger内存缓存的利用率,进一步提高查询速度

  • 简化处理时间序列数据的工作复杂度

在常规集合中,数据按顺序存储在磁盘上的块中,优化了写入速度。然而,它需要为每个数据点创建一个索引,这会迅速增长得非常大。它还需要第二个索引,其中包含时间序列标识符和自身的时间戳,以便用户可以查询单个序列。为了读取这些数据,MongoDB必须处理包含它的所有数据库和磁盘块,即使一个块只包含一个相关的文档。

此模型优化了CRUD操作和频繁的更新。银行账户余额只需要反映当前状态,因此每个账户持有人的文档会随着信息的更改而更新。

将此与时间序列集合进行比较。时间序列集合按顺序写入数据,这意味着最近的事务可以保留在内存中以便更快地检索。由于它们按顺序写入,因此文档存储在一起,因此不需要在文档不再在内存后读取每个磁盘块。数据按metaField索引,导致索引大小更小。

当你创建一个时间序列集合时,MongoDB会自动创建一个system.buckets 系统集合。MongoDB将具有以下两个属性

  • 具有相同metaField值(该值应唯一标识时间序列)的文档分组。如果metaField是一个对象或数组,MongoDB只有在所有对象字段或数组元素匹配的情况下才会进行分组。

  • 彼此时间相近的timeField值。时间序列集合的granularitybucketMaxSpanSecondsbucketRoundingSeconds参数控制每个桶覆盖的时间跨度。更多信息,请参阅设置时间序列数据粒度

例如,如果粒度为,MongoDB会将同一小时的文档归入一个桶。如果一个桶包含一个具有metaField值为sensorAtimeField值为2024-08-01T18:23:21Z的文档,那么一个具有metaField值为sensorB的传入文档将进入一个单独的桶,无论时间如何。只有当来自sensorA的传入文档的timeField值在2024-08-01T18:00:00Z2024-08-01T18:59:59Z之间时,它才会进入同一个桶。

如果一个时间值为2023-03-27T16:24:35Z的文档不适合现有的桶,MongoDB将创建一个新桶,其最小时间为2023-03-27T16:00:00Z,最大时间为2023-03-27T19:59:59Z

注意

你可以修改时间序列集合的粒度,但只能从更细的度量更改到更粗的度量,例如将桶覆盖范围从分钟扩展到小时。这将更新集合的视图定义,但不会改变现有桶中数据的存储方式。

由于metaField的值必须与分组文档完全匹配,因此时间序列集合中的桶的数量取决于唯一的metaField值的数量。具有细粒度或变化的metaField值的集合会产生许多稀疏填充的、短期存在的桶。这会导致存储和查询效率降低。

例如,在以下文档中,metadata是选择metaField的好选择,因为它使得从给定的气象传感器查询数据变得容易。使用这些字段,MongoDB将单个传感器的读数组合在一起。

{
timestamp: ISODate("2021-05-18T00:00:00.000Z"),
metadata: { sensorId: 5578, type: 'temperature' },
temp: 12,
_id: ObjectId("62f11bbf1e52f124b84479ad")
}

桶目录是WiredTiger中的一个专门的内存缓存。它跟踪桶以最小化延迟并协调并发写入。

对于每个打开的桶,目录维护有关信息,例如metaField、活动写入者、覆盖时间范围、文档数量、大小和最近操作。由于MongoDB为具有不同metaField的文档创建单独的桶,通常同时打开多个桶。

为了避免竞争条件导致的不一致性,在执行冲突操作时,可能会关闭桶并将其从桶目录中删除。重启mongod关闭所有桶并重置桶目录。

  • MongoDB会在没有适合接收文档的桶时创建一个新的桶。这发生在以下任何一种情况为真时

    • 文档 metaField 与任何活动桶都不匹配。

    • 文档的时间戳超出了所有活动桶的范围。

    • 文档超过了所有活动桶的剩余大小或文档限制。

    新桶的起始时间戳基于集合的 粒度 向下取整。这处理了顺序不正确的文档连续到达的情况。

MongoDB 在以下任一情况下关闭桶

  • 时间向前或向后移动超出了覆盖的时间范围,如由落在桶范围之外的传入文档时间戳所示。这些界限由集合的 粒度 设置确定。

  • 桶达到了文档限制(默认1000)。

  • 桶超过了其存储大小限制。这发生在

    • 大小超过了允许的最大值(默认125KiB)。

    • 文档数量低于一个最小数量(默认10)且大小低于12MiB。

      这是一个内部限制,当数据由更少、更大的文档组成时,它可以优化性能。

    • 活动桶的集合无法适应允许的存储引擎缓存大小。您可以使用 collStats 数据库命令来查看此信息。

  • 桶目录超过了其允许的总内存分配量(默认为可用系统内存的2.5%)

  • 冲突操作,如块迁移或更新,改变了桶的磁盘状态。

  • mongod 重新启动。这关闭了所有桶。

MongoDB在以下情况下删除一个桶:

返回

时间序列