文档文档

优化 Flux 查询

此页面记录了早期版本的 InfluxDB OSS。InfluxDB OSS v2 是最新的稳定版本。请参阅 InfluxDB v2 文档

优化您的 Flux 查询以减少其内存和计算 (CPU) 需求。

使用下推启动查询

下推 是将数据操作推送到底层数据源而不是在内存中操作数据的函数或函数组合。使用下推启动查询以提高查询性能。一旦非下推函数运行,Flux 会将数据拉入内存并在那里运行所有后续操作。

下推函数和函数组合

InfluxDB OSS 1.11+ 中支持以下下推。

函数支持
count()
drop()
duplicate()
filter() *
fill()
first()
group()
keep()
last()
max()
mean()
min()
range()
rename()
sum()
window()
函数组合
group() |> max()
group() |> min()
window() |> count()
window() |> first()
window() |> last()
window() |> max()
window() |> min()
window() |> sum()

* filter() 仅在所有参数值都是静态时才下推。请参阅 避免内联处理过滤器

在查询的开头使用下推函数和函数组合。一旦非下推函数运行,Flux 会将数据拉入内存并在那里运行所有后续操作。

正在使用的下推函数
from(bucket: "db/rp")
    |> range(start: -1h)                       //
    |> filter(fn: (r) => r.sensor == "abc123") //
    |> group(columns: ["_field", "host"])      // Pushed to the data source
    |> aggregateWindow(every: 5m, fn: max)     //
    |> filter(fn: (r) => r._value >= 90.0)     //

    |> top(n: 10)                              // Run in memory

避免内联处理过滤器

避免使用数学运算或字符串操作内联定义数据过滤器。内联处理过滤器值会阻止 filter() 将其操作下推到底层数据源,因此先前函数返回的数据会加载到内存中。这通常会导致显着的性能下降。

例如,以下查询使用 Chronograf 仪表板模板变量 和字符串连接来定义要筛选的区域。由于 filter() 内联使用字符串连接,因此它无法将其操作下推到底层数据源,并将从 range() 返回的所有数据加载到内存中。

from(bucket: "db/rp")
    |> range(start: -1h)                      
    |> filter(fn: (r) => r.region == v.provider + v.region)

要动态设置过滤器并保持 filter() 函数的下推能力,请使用变量在 filter() 外部定义过滤器值

region = v.provider + v.region

from(bucket: "db/rp")
    |> range(start: -1h)                      
    |> filter(fn: (r) => r.region == region)

避免短窗口持续时间

窗口化(基于时间间隔对数据进行分组)通常用于聚合和下采样数据。通过避免短窗口持续时间来提高性能。更多窗口需要更多计算能力来评估应将每行分配给哪个窗口。合理的窗口持续时间取决于查询的总时间范围。

谨慎使用“重型”函数

以下函数比其他函数使用更多的内存或 CPU。在使用它们之前,请考虑它们在数据处理中的必要性

尽可能使用 set() 而不是 map()

set()experimental.set()map 都可以设置数据中的列值,但是 set 函数比 map() 具有性能优势。

使用以下指南来确定使用哪个

  • 如果将列值设置为预定义的静态值,请使用 set()experimental.set()
  • 如果使用现有行数据动态设置列值,请使用 map()

将列值设置为静态值

以下查询在功能上是相同的,但使用 set() 比使用 map() 性能更高。

data
    |> map(fn: (r) => ({ r with foo: "bar" }))

// Recommended
data
    |> set(key: "foo", value: "bar")

使用现有行数据动态设置列值

data
    |> map(fn: (r) => ({ r with foo: r.bar }))

平衡时间范围和数据精度

为确保查询性能良好,请平衡时间范围和数据的精度。例如,如果您查询每秒存储的数据并请求六个月的数据,则结果将包括每个序列 ≈1550 万个点。根据 filter() (基数) 后返回的序列数,这可能很快变成数十亿个点。Flux 必须将这些点存储在内存中才能生成响应。使用 下推 来优化内存中存储的点数。

使用 Flux 分析器测量查询性能

使用 Flux Profiler 包 来衡量查询性能并将性能指标附加到您的查询输出。以下 Flux 分析器可用

  • query:提供有关整个 Flux 脚本执行的统计信息。
  • operator:提供有关查询中每个操作的统计信息。

导入 profiler 包并使用 profile.enabledProfilers 选项启用分析器。

import "profiler"

option profiler.enabledProfilers = ["query", "operator"]

// Query to profile

有关 Flux 分析器的更多信息,请参阅 Flux Profiler 包


此页是否对您有帮助?

感谢您的反馈!


Flux 的未来

Flux 即将进入维护模式。您可以继续像现在一样使用它,而无需对代码进行任何更改。

阅读更多

InfluxDB 3 开源版本现已发布公开 Alpha 版

InfluxDB 3 开源版本现已可用于 Alpha 测试,根据 MIT 或 Apache 2 许可获得许可。

我们正在发布两个产品作为 Alpha 版本的一部分。

InfluxDB 3 Core 是我们新的开源产品。它是用于时间序列和事件数据的最新数据引擎。InfluxDB 3 Enterprise 是一个商业版本,它建立在 Core 的基础上,增加了历史查询功能、读取副本、高可用性、可扩展性和细粒度的安全性。

有关如何入门的更多信息,请查看