文档化档

使用 Flux 计算百分比

查看等效的 InfluxDB v2 文档: 使用 Flux 计算百分比.

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

计算百分比

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

以下示例使用 pivot() 将操作数对齐到行,因为 pivot() 在大多数情况下都有效,并且比 join() 性能更好。参见 Pivot vs 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 集群版现已正式发布

新功能,包括更快的查询性能和管理工具,推进了 InfluxDB v3 产品线。InfluxDB 集群版现已正式发布。

InfluxDB v3 性能和功能

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

了解 v3 增强功能


InfluxDB 集群版正式发布

InfluxDB 集群版现已正式发布,为您在自管理堆栈中提供 InfluxDB v3 的功能。

与我们讨论 InfluxDB 集群版