Docs 菜单
Docs 主页
/
MongoDB Manual
/

关于时间序列数据

在此页面上

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

在内部, MongoDB根据常见的 metaField值对时间序列集合中的文档进行分组,从而优化时间序列数据。选择一个有用的可显着优化存储密度和查询性能。有关更多信息,请参阅元字段。

时间序列数据具有几个有别于其他数据格式的属性:

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

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

  • 如果您的应用程序受益于大量的历史记录,则很少会执行删除操作。

  • 数据按时间和标识符(例如股票报价器)进行索引,该标识符可标识数据所属的唯一时间序列。

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

考虑到这些因素, MongoDB使用专门的柱状格式将每个时间序列的文档分组在一起。这样做有以下好处:

  • 减少存储和索引大小

  • 提高查询效率

  • 减少读取操作的 I/O 量

  • 提高WiredTiger内存缓存的使用率,进一步提高查询速度

  • 降低处理时间序列数据的复杂性

在常规集合中,数据作为块按顺序存储在磁盘上,从而优化了写入速度。但是,它需要为每个数据点建立一个索引,而该索引很快就会变得非常大。它还需要第二个索引,其中包含时间序列标识符和时间戳本身,以便用户可以查询单个序列。要读取此数据, MongoDB必须进程包含该数据的所有数据库和磁盘区块,即使某个区块仅包含一个相关文档。

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

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

当您创建时间序列集合时, MongoDB会自动创建一个system.buckets系统集合。 MongoDB对同时具备以下条件的文档进行分组:

  • 相同的metaField值,应唯一标识时间序列。如果metaField是对象或大量,则仅当所有对象字段或大量元素都匹配时, MongoDB才会进行分组。

  • timeField 值相近的值。时间序列集合的granularitybucketMaxSpanSecondsbucketRoundingSeconds参数控制每个存储桶涵盖的时间跨度。有关详细信息,请参阅设置时间序列数据的粒度。

示例, MongoDB在同一小时内以seconds的粒度对文档进行存储桶。如果存储桶文档metaField值为sensorAtimeField值为2024-08-01T18:23:21Z的文档,则metaFieldsensorB的传入文档无论何时都会放入单独的存储桶中。仅当来自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值的集合会生成许多稀疏填充的短期存储桶。这会导致存储和查询效率。

示例,在以下文档中, metadatametaField不错的选择,因为它可以轻松查询来自给定天气传感器的数据。 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 )。

  • 存储桶已超过其存储大小限制。在以下情况下会发生这种情况:

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

    • 文档数量低于最小数量(默认为10 ),大小低于12 MiB。

      这是一设立内部限制,可在数据由较少但较大的文档组成时优化性能。

    • 活动存储桶设立不符合允许的存储引擎缓存大小。您可以使用collStats数据库命令查看此信息。

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

  • 冲突操作(例如数据数据块迁移或更新)会更改存储桶的磁盘上状态。

  • mongod 重新启动。这将关闭所有存储桶。

MongoDB在以下情况下删除存储桶:

后退

时间序列