0

我有一个 MongoDB 文档设计,将数组数据存储在 6 个顶级属性字段中。该文档主要存储当天从一组特定传感器收集的物联网数据,并且全天更新非常频繁(每 2 秒一次)。每个新的传感器数据包都将数据附加到所有 6 个数组的末尾,这意味着到一天结束时,每个数组最多可以有 43200 个值(即使它永远不会得到那么多)。

基本结构如下:

{
  _id: string,
  tracker: string,
  startTime: Date,
  endTime: Date,
  sensor1: number[],
  sensor2: number[],
  path: { 
    type: "Linestring",
    coordinates: number[][],
  },
  times: Date[],
  ...
}

最近,我们的数据库似乎一直在“与高 I​​OPS 作斗争”,我们认为这可能是由于不断附加到这些数组造成的。根据 MongoDB 顾问的说法,过去几个月的几次主要重启都是这种情况,尽管我们的层允许 3000 IOPS,而我们在高峰时间最多只能达到 2000。我们目前在 Atlas 上运行一个 M30 层的副本集。

MongoDB 建议应避免使用无界数组,因为如果文档的大小超出分配的空间,则会在磁盘上移动文档。对于 MMAP 存储引擎来说,这似乎是一个明显的问题,但根据他们的文档,这已通过使用 WiredTiger 存储引擎的 MongoDB 4.0 解决。

所以我想我的问题如下:

  1. 有人可以确认一旦它们超出分配的大小,WiredTiger 存储引擎是否也会在磁盘上移动文档?这种情况多久会发生一次,这会产生重大影响吗?文档还指出,存储是按 2 的幂分配的。如果是这种情况,那么单个文档应该只有最少的“文档移动”,因为这会随着文档大小呈指数增长?

  2. 考虑到我仍然需要访问未处理/未计算的数据这一事实,如果有的话,存储这些数据的更好方法是什么?

提前致谢!

4

1 回答 1

0

更新一个文档 => 将文档加载到内存中(您可以做简单的基准测试来测试它)
当文档变大 => 每次更新成本更高

解决方案=> 通过减少时间范围来保持更小的数组。

你有 1 天的时间范围,你可以让它像 5 小时或 1 小时。
(为了得到你可以分组的全天测量)我认为在你的情况下只有更短的时间范围=>更小的数组,这就足够了一种方法是有一个额外的字段{:id 1, :hour 1} {:id 1 ,:hour 2} ...,新的小时字段应该被索引.

据我所知,文档已移动,但 MongoDB 有办法通过预先分配空间来快速完成此操作如果您需要更多内部信息,您也可以在此处询问, 但我不认为这是您的问题或您会找到一种更新和快速、大文件的方法。(你更新得太频繁了,所以大小会导致问题)

*也许比我的解决方案更好的方法,最好也等待其他答案。

于 2021-09-20T20:55:31.020 回答