文档

使用 Flux 计算百分比

本页介绍了 InfluxDB OSS 的早期版本。 InfluxDB OSS v2 是最新稳定版本。 查看等效的 InfluxDB v2 文档: 使用 Flux 计算百分比

从查询数据中计算百分比是时间序列数据的常见用例。要在 Flux 中计算百分比,操作数必须在每一行中。使用 map() 重新映射行中的值并计算百分比。

要计算百分比

  1. 使用 from()range()filter() 查询操作数。
  2. 使用 pivot()join() 将操作数值对齐到行。
  3. 使用 map() 将分子操作数值除以分母操作数值,然后乘以 100。

以下示例使用 pivot() 将操作数对齐到行,因为 pivot() 在大多数情况下都有效,并且比 join() 性能更好。 请参阅 Pivot 与 Join

from(bucket: "db/rp")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "m1" and r._field =~ /field[1-2]/ )
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({ r with _value: r.field1 / r.field2 * 100.0 }))

GPU 监控示例

以下示例查询 gpu-monitor 存储桶中的数据,并计算 GPU 内存使用率的百分比。数据包括以下内容

  • gpu 测量
  • mem_used 字段:使用的 GPU 内存字节数
  • mem_total 字段:总 GPU 内存字节数

查询 mem_used 和 mem_total 字段

from(bucket: "gpu-monitor")
  |> range(start: 2020-01-01T00:00:00Z)
  |> filter(fn: (r) => r._measurement == "gpu" and r._field =~ /mem_/)
返回以下表流
_time_measurement_field_value
2020-01-01T00:00:00Zgpumem_used2517924577
2020-01-01T00:00:10Zgpumem_used2695091978
2020-01-01T00:00:20Zgpumem_used2576980377
2020-01-01T00:00:30Zgpumem_used3006477107
2020-01-01T00:00:40Zgpumem_used3543348019
2020-01-01T00:00:50Zgpumem_used4402341478

_time_measurement_field_value
2020-01-01T00:00:00Zgpumem_total8589934592
2020-01-01T00:00:10Zgpumem_total8589934592
2020-01-01T00:00:20Zgpumem_total8589934592
2020-01-01T00:00:30Zgpumem_total8589934592
2020-01-01T00:00:40Zgpumem_total8589934592
2020-01-01T00:00:50Zgpumem_total8589934592

将字段转换为列

使用 pivot()mem_usedmem_total 字段转换为列。输出包括 mem_usedmem_total 列,以及每个对应 _time 的值。

// ...
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
返回以下内容
_time_measurementmem_usedmem_total
2020-01-01T00:00:00Zgpu25179245778589934592
2020-01-01T00:00:10Zgpu26950919788589934592
2020-01-01T00:00:20Zgpu25769803778589934592
2020-01-01T00:00:30Zgpu30064771078589934592
2020-01-01T00:00:40Zgpu35433480198589934592
2020-01-01T00:00:50Zgpu44023414788589934592

映射新值

现在每一行都包含计算百分比所需的值。使用 map() 重新映射每一行中的值。将 mem_used 除以 mem_total 并乘以 100 以返回百分比。

要返回包含小数点的精确浮点百分比值,下面的示例将整数字段值转换为浮点值,然后乘以浮点值(100.0)。

// ...
  |> map(fn: (r) => ({
    _time: r._time,
    _measurement: r._measurement,
    _field: "mem_used_percent",
    _value: float(v: r.mem_used) / float(v: r.mem_total) * 100.0
  }))
查询结果
_time_measurement_field_value
2020-01-01T00:00:00Zgpumem_used_percent29.31
2020-01-01T00:00:10Zgpumem_used_percent31.37
2020-01-01T00:00:20Zgpumem_used_percent30.00
2020-01-01T00:00:30Zgpumem_used_percent35.00
2020-01-01T00:00:40Zgpumem_used_percent41.25
2020-01-01T00:00:50Zgpumem_used_percent51.25

完整查询

from(bucket: "gpu-monitor")
  |> range(start: 2020-01-01T00:00:00Z)
  |> filter(fn: (r) => r._measurement == "gpu" and r._field =~ /mem_/ )
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({
    _time: r._time,
    _measurement: r._measurement,
    _field: "mem_used_percent",
    _value: float(v: r.mem_used) / float(v: r.mem_total) * 100.0
  }))

示例

使用多个字段计算百分比

from(bucket: "db/rp")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "example-measurement")
  |> filter(fn: (r) =>
    r._field == "used_system" or
    r._field == "used_user" or
    r._field == "total"
  )
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({ r with
    _value: float(v: r.used_system + r.used_user) / float(v: r.total) * 100.0
  }))

使用多个测量值计算百分比

  1. 确保测量值在同一个 存储桶 中。
  2. 使用 filter() 包含来自两个测量值的 数据。
  3. 使用 group() 解组数据并返回单个表。
  4. 使用 pivot() 将字段转换为列。
  5. 使用 map() 重新映射行并进行百分比计算。
from(bucket: "db/rp")
  |> range(start: -1h)
  |> filter(fn: (r) =>
    (r._measurement == "m1" or r._measurement == "m2") and
    (r._field == "field1" or r._field == "field2")    
  )
  |> group()
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({ r with  _value: r.field1 / r.field2 * 100.0 }))

使用多个数据源计算百分比

import "sql"
import "influxdata/influxdb/secrets"

pgUser = secrets.get(key: "POSTGRES_USER")
pgPass = secrets.get(key: "POSTGRES_PASSWORD")
pgHost = secrets.get(key: "POSTGRES_HOST")

t1 = sql.from(
  driverName: "postgres",
  dataSourceName: "postgresql://${pgUser}:${pgPass}@${pgHost}",
  query:"SELECT id, name, available FROM exampleTable"
)

t2 = from(bucket: "db/rp")
  |> range(start: -1h)
  |> filter(fn: (r) =>
    r._measurement == "example-measurement" and
    r._field == "example-field"
  )

join(tables: {t1: t1, t2: t2}, on: ["id"])
  |> map(fn: (r) => ({ r with _value: r._value_t2 / r.available_t1 * 100.0 }))

这个页面有帮助吗?

感谢您的反馈!


Flux的未来

Flux将进入维护模式。您可以继续按照当前方式使用它,而无需对代码进行任何更改。

阅读更多

InfluxDB v3增强功能和InfluxDB Clustered现已上市

新功能包括更快的查询性能和管理工具,推进了InfluxDB v3产品线。InfluxDB Clustered现已上市。

InfluxDB v3性能和功能

InfluxDB v3产品线在查询性能方面取得了重大提升,并提供了新的管理工具。这些增强包括一个操作仪表板来监控InfluxDB集群的健康状况,InfluxDB Cloud Dedicated中的单点登录(SSO)支持,以及针对令牌和数据库的新管理API。

了解新的v3增强功能


InfluxDB Clustered上市

InfluxDB Clustered现已上市,并为您在自管理堆栈中提供了InfluxDB v3的功能。

与我们谈谈InfluxDB Clustered