InfluxDB:单次或多次测量

InfluxDB : single or multiple measurement

我是 influxDB 的初学者,在阅读了 Schema design 文档后,我仍然有一个问题。

如何决定是应该使用一个测量多个字段还是多个测量一个字段?

我有多个物联网设备,每分钟发送一次数据(温度、湿度、压力)。所有这些数据都有完全相同的时间戳。

所以我想知道是否要像这样创建一个测量值:

    timestamp,iotid,temperature,humidity,pressure
-------------------------------------------------
    1501230195,iot1,70,         45,      850

或者 3 个测量值(每个值一个),具有相同的标签但其中只有一个字段?

timestamp,iotid,temperature
----------------------------
    1501230195,iot1,70

timestamp,iotid,humidity
-------------------------
    1501230195,iot1,45

timestamp,iotid,pressure
-------------------------
    1501230195,iot1,850

在查询方面,我只能检索一个值,但同时也可以检索 3 个值。

这可能取决于您的数据,请尝试两者并查看存储要求。 例如,如果湿度变化不大,则将其分开是有意义的。但是,如果某些变量在相似的时间间隔内发生变化,那么将它们组合起来就有意义了。它还可能取决于您的查询模式。

两种模式设计都没有对错之分,但使用一个测量一个字段值是更合适的方法。

为什么?

将多个字段值存储到一个 measurement 中是一个非常关系数据库的事情。也就是说,measurement 不应被视为 database table,因为它是完全不同的东西。

应明确保留测量值以描述一种数据类型,例如温度或 CPU 使用情况。

如果我们使用 one field value per measurement 设计我们的模式,那么我们可以用真实的英语描述数据,例如;

在某个point时间,温度measureddata value=30。请注意此处使用的术语 pointdatameasurement.

而如果您将多个 field values 放入特定的 measurement 中,那么您会发现很难用真正的英语呈现 data

influxdb 是一个时间序列数据库,所以很明显我们应该按照 time-series 的方式来做。

另外,有些时间序列数据实际上是精确到微秒级别的。在如此细粒度的时序中,即使 milliseconds 一组数据也不太可能共享相同的时序。因此,将其设计为包含一系列数据点的一个测量始终是更好的选择。

有点老问题了,但这可能与任何从事 TSDB 工作的人都相关。

当我刚开始的时候,我的方法是每个数据点都进入一个单一的领域测量。假设我稍后会在 SQL 语句中合并我需要的数据。但是,任何使用过像 influx 这样的 TSDB 的人都知道,由于实现 TSDB 时使用的设计选择,在数据检索方面存在一些严重的限制。

随着我在项目中的推进,以下是我制定的经验法则:

测量应包含使其有意义所需的所有维度,但仅此而已。

示例:想象一个给出 3 个信号的气体流量计:

  • 体积流量
  • 温度
  • 总流量

在这种情况下,体积流量和温度应该是单个测量的两个字段,总流量应该是它自己的测量。

(如果 reader 不喜欢这个例子,想想一个输出安培和伏特以及 kw 和 pf 的家用电表)。

为什么将体积和温度存储在不同系列中会不好?

  1. 时间:如果将这两个测量值存储在不同的系列中,它们将具有不同的索引值(时间戳)。除非您注意确保它们已明确指定时间戳,否则您 运行 可能会冒它们被轻微抽样的风险。这很可能最终成为一件坏事 (tm),因为您可能会在数据中引入系统测量偏差。即使这不是一件坏事,但如果您以后想重用这些数据(例如将其转储到 csv 文件中),那将会非常烦人。

  2. 效用:如果你想推导出体积流量,你必须得到constant * temp * volume才能得到正确的值。使用两个单独的测量来执行此操作将成为一场噩梦,因为例如 influxdb 甚至不支持该操作。但即使这样做了,您也必须确保未正确处理其中一个字段的缺失值,并且正确完成分组和聚合。

为什么将所有三个存储在一次测量中会不好?

您很可能有这样一个用例,您希望始终审核所有三个值,但很可能情况并非如此,您不关心以相同频率测量总体积您想测量流量本身。

将所有字段放在一个测量值中将迫使您在某些字段中输入空值,或者始终记录几乎没有变化的变量。不管怎样,效率都不高。

重要的见解是,多维实体需要它们的所有维度同时 time 才有意义。

我想提一下还有一个有效的第三个选项:

timestamp,iotid,measure,value
----------------------------
1501230195, iot1, temperare, 70
1501230195, iot1, humidity, 45
1501230195, iot1, pressure, 850