跳至主要内容

时间序列类型格式

所有基于时间序列的格式的共享属性

  • 框架应按时间列/字段升序排序3
  • 时间字段
    • 不应包含空值
    • 字段名称仅用于显示目的,不应有标签
    • 对于每个框架,第一个时间字段之后的任何其他时间字段都被视为剩余数据
  • 值字段
    • 值字段之所以这样命名,是因为它是每个数据点(时间,值)的所在字段。
    • 它可以是数值或布尔字段。对于数值
      • Go: Float64,*Float64 或 Int64 等
      • 在 JS 中为 'number'
    • 序列名称来自值字段的名称属性

无效情况

  • 至少不存在时间字段和值字段(除非是单帧“无数据”情况)
  • 存在“无数据”情况(一个没有字段的框架)以及数据
  • 可能是警告而不是错误
    • 重复项(通过名称+维度识别)
    • 未排序(时间未从旧到新排序)

时间序列宽格式 (TimeSeriesWide)

版本:0.1

宽格式在一个共享相同时间字段的单个框架中具有一组时间序列。之所以称为“宽”,是因为随着添加更多序列,它会变得更宽

示例

类型:时间
名称:T
标签:nil
类型:数字
名称:cpu
标签:{"host": "a"}
类型:数字
名称:cpu
标签:{"host": "b"}
2022-04-27 5:0016
2022-04-27 6:0048
2022-04-27 7:0025
2022-04-27 8:0039

它应具有以下属性:(另请参见共享属性)

  • 第一个类型为时间的字段是所有时间序列的时间索引。
  • 应该只有一个框架具有数据类型声明。
  • 应该至少有一个字段是值字段类型
  • 如果有多个数值字段,则框架中时间字段与每个值字段的组合会创建每个时间序列(指标)
  • 时间字段不应包含重复值(重复时间戳)。

剩余数据

  • 任何没有类型声明或不同声明的附加框架
  • 框架中的任何字符串字段

备注

  • 此内容的 Go 示例近似值在此

时间序列多格式 (TimeSeriesMulti)

版本:0.1

TimeSeriesMulti 格式每个框架一个时间序列。如果响应有多个序列,其中时间值可能不一致,则必须使用此格式而不是 TimeSeriesWide。之所以称为“多”,是因为数据存在于多个数据框架中。

示例:

框架 0

类型:时间
名称:T
标签:nil
类型:数字
名称:cpu
标签:{"host": "a"}
2022-04-27 5:001
2022-04-27 6:004
2022-04-27 7:002
2022-04-27 8:003

框架 1

类型:时间
名称:T
标签:nil
类型:数字
名称:cpu
标签:{"host": "b"}
2022-04-27 5:006
2022-04-27 6:008
2022-04-27 7:005
2022-04-27 8:009

它应具有以下属性:(另请参见共享属性)

  • 每个框架应至少包含时间和一个数值列。此类型的每个字段的第一次出现用于序列。
  • 不同的框架可以具有不同的字段长度(但在一个框架内,它们必须具有相同的长度)
  • 每个时间字段不应包含重复值(重复时间戳)

剩余数据

  • 每个框架中第一个之后的所有数值或时间字段
  • 任何没有类型声明或不同声明的附加框架
  • 框架中的任何字符串字段

备注

  • Go 示例在此
  • 多格式是唯一可以从其他格式转换而无需数据操作的格式。因此,它是一种可以包含所有其他类型序列信息的类型。

时间序列长格式 (TimeSeriesLong)[类似 SQL]

版本:0.1

这是一种类似 SQL 系统的常见响应格式4。请参阅Grafana 文档:表格式中的多个维度,以获取一些更简单的(但不完整)示例。它目前作为一些数据源5中的数据转换存在于后端,这些数据源查询类似 SQL 的数据,请参阅此 Go 示例了解代码的工作原理

之所以称为“长”,是因为与“宽”格式相比,它具有更多行来保存相同的序列,因此它会变得更长

示例

类型:时间
名称:T
标签:nil
类型:字符串
名称:host
标签:nil
类型:数字
名称:cpu
标签:nil
2022-04-27 5:00a1
2022-04-27 5:00b6
2022-04-27 6:00a4
2022-04-27 6:00b8
2022-04-27 7:00a2
2022-04-27 7:00b5
2022-04-27 8:00a3
2022-04-27 8:00b9

它应具有以下属性:(另请参见共享属性):

  • 第一个时间字段用作时间戳
  • 时间字段可以具有重复时间戳(但必须按时间升序排序)
  • 可以选择性地包含字符串字段。对于每个字符串字段
    • 列/字段名称是维度(例如“标签”)名称
    • 该字段中相应的字符串值(按行)是标签值
  • 通过迭代数据帧表响应的行来构建序列。
  • 任何值字段/列的名称都成为每个序列的名称
  • 字段的标签属性未使用

剩余数据

  • 第一个之后的所有其他时间字段
  • 任何没有类型声明或不同声明的附加框架

其他属性或注意事项

  • 在此格式中,完整的维度(例如“host”=value)是从字段中的值中提取的,而不是像其他格式那样在字段模式中声明。
  • 由于维度表示在所有派生序列中都存在的字段中,因此它不能保存混合维度键,因此所有序列都将具有相同的维度键集。例如,一个人不能拥有 net.bytes{host="a"}和 net.bytes{host="a",int="eth0"}在一起 - 第一个必须变成 net.bytes{host="a",int=""}
  • 尚不清楚布尔类型字段是否应被视为值字段(例如上下指标)或维度(在这种情况下,它在概念上将被视为标签)

时间序列格式之间的转换

目标修改数据属性
[^6]
  • 一个框架到多个框架
  • 转换到多格式时,每个值(数值)字段以及宽框架中时间字段的副本将移动到其自己的单个框架中
  • 多个框架到一个框架
  • 必须执行联合:多格式中所有框架的所有时间字段都必须成为宽框架的一个时间字段
  • 每个值字段都移动到宽框架中
  • 所有值(数值)字段的长度必须与宽框架中的时间字段相同,因此可能需要使用零值(可能是 null)填充值字段,从而有效地创建之前可能不存在的数据点
[^7]
  • 一个框架到一个框架
  • 标签从值字段中提取,并成为一个字符串字段,其名称与所有标签中找到的所有键匹配。标签值成为相应字段中的字段值。
  • 由于字符串字段将存在,因此一个序列存在的标签/维度键必须存在于所有序列中,因此序列可能会在该标签键不存在的情况下被更改(可能值为 null)。这实际上可能会创建之前不存在的序列
是[^8]
  • 一个框架到一个框架
  • 字符串字段成为值(数值)字段上的标签(标签键来自字段名称,标签值来自字段的值。)
  • 长框架中单个时间字段中的重复时间戳在宽框架中的时间字段中被去重
  • 由于长格式的数据中可能缺少行(时间戳),因此可能需要在序列中插入 null 以使它们都共享相同的时间字段(宽的一个属性)
  • 一个框架到多个框架(每个框架一个序列)
  • 匹配该时间序列时,将构建每个框架的时间字段
  • 多格式框架中的标签成为长格式框架中的字符串字段,并且字符串列存在于长格式框架的所有行中。因此,标签键可能会添加到序列中

备注


  1. 这是因为在大多数情况下,排序通常在资源方面代价高昂,并且最好由数据源背后的数据库完成。
  2. 我不认为我们当前的 SQL 数据源严格遵循此规则,但一些 Azure 数据源确实遵循。这是由于对这种格式的意图和升级到 Grafana 8 的沟通不畅和/或对重大更改缺乏了解,或者两者兼而有之。
  3. 当使用“格式为=时间序列”进行查询时,会发生此转换。此转换发生在管道此阶段的问题在于,虽然它确实为用户提供了表格式中的通用时间序列的时间序列,但它使数据的“表视图”与来自其查询的 SQL 返回不一致。待办事项:稍后定义此一般概念,也许将其称为“您看到的内容不是您得到的内容”、“数据通信错误”等。这意味着我们需要返回两件事(有点像示例?),或者操作应该被移动,或者其他什么。