跨 InfluxDb 指标查询?

Posted

技术标签:

【中文标题】跨 InfluxDb 指标查询?【英文标题】:Query across InfluxDb metrics? 【发布时间】:2017-04-20 06:46:48 【问题描述】:

我在 InfluxDb 数据库中有 3 个时间序列指标,类似于:

myservice_processed
myservice_invoked
myservice_error

为了获得一组时间序列的值,我有一个 grafana 图来映射:

select sum(value) from myservice_processed where $timeFilter GROUP BY time($interval) fill(null)

...对于三个值中的每一个。这给出了每分钟发生多少次调用、成功和失败的想法。一般processederror之和应该等于invoked的值。

现在我想根据上述指标获得一个时间序列值,它给出了失败的百分比。例如,在任何给定的时间间隔内,我可能有 1000 次调用,其中 900 次处理和 100 次错误;我希望该指标在该区间内为 10%。

对于我的生活,我无法弄清楚如何做到这一点,并且我开始怀疑它无法做到,这让我难以置信。有人可以告诉我我错了并告诉我该怎么做吗?

【问题讨论】:

【参考方案1】:

目前这是不可能的,因为 Influxdb 目前不支持多个系列的聚合功能(influxdb 1.0)

到目前为止,Grafana 不支持时间序列计算,但我们确实有问题的票https://github.com/grafana/grafana/issues/3677

【讨论】:

【参考方案2】:

这可以通过一组连续查询在 InfluxDB 中完成。

InfluxDB 的工作原理似乎是存储成本低,而计划外的处理器时间成本高。设置存储结果的后台连续计算很容易,它可以让计算在后台悄悄地搅动。在 InfluxDB 中进行即时计算很快就会变得很尴尬(或者不可能,如果它们跨越测量)。

策略

每个例如五分钟,对每个指标进行求和,按时间分组,然后将总和插入第四次测量,称为myservice_summary

myservice_summary 将有多个字段,而不是一个名为 value 的字段;一种用于调用的调用,一种用于已处理的调用,一种用于有错误的调用。我们将字段命名为对读取数据的人有意义的名称,而不是默认名称 value

请注意,使用GROUP BY time(x) 压缩数据(在此示例中,每五分钟一次)还可以减少存储开销和客户端查询时间(在客户端上检索、传输和显示的点更少)。它还减少了存储需求。 InfluxDB 中通常使用至少两种保留策略:原始数据在短时间内(例如 30 天)被修剪,经过压缩和处理的数据可以保留更长时间(例如几个月、几年……)

当然,选择太大的GROUP BY time() 间隔意味着粗分辨率可能不利于故障查找。例如当您需要知道在什么小时内开始查找特定更改时,使用 GROUP BY time(1d) 并没有多大用处。

最佳时间分组窗口可在问题开始/停止的有意义检测与客户端响应速度和存储负载之间取得平衡。找到这个最佳值留作练习。 :)

示例

请注意,在使用 CLI 时,对于以下三个连续查询中的每一个,从 CREATE CONTINUOUS QUERYEND 的所有内容都可能需要位于一行以避免语法错误。我插入换行符只是为了提高可读性。

方括号[ ] 表示可选参数。括号本身不应按字面意思包括在内。

在这种情况下,您将使用额外的标签键来选择哪些键是重要的并且应该在新的测量中。

CREATE CONTINUOUS QUERY myservice_processed_sum_5m ON your_db_name
BEGIN
    SELECT sum(value) AS processed_sum_5m 
    INTO myservice_summary 
    FROM myservice_processed GROUP BY time(5m)[, other_tag_keys e.g. vendor_id]
END 

CREATE CONTINUOUS QUERY myservice_invoked_sum_5m ON your_db_name
BEGIN
    SELECT sum(value) AS invoked_sum_5m 
    INTO myservice_summary 
    FROM myservice_invoked GROUP BY time(5m)[, other_tag_keys e.g. vendor_id]
END 

CREATE CONTINUOUS QUERY myservice_error_sum ON your_db_name
BEGIN
    SELECT sum(value) AS error_sum_5m 
    INTO myservice_summary 
    FROM myservice_error GROUP BY time(5m)[, other_tag_keys e.g. vendor_id]
END

所以现在我们有了一个名为 myservice_summary 的新度量,它包含三个字段:processed_sum_5minvoked_sum_5merror_sum_5m(假设您需要 5 分钟的摘要)。

从那里查询过去 24 小时的失败百分比是:

SELECT (error_sum_5m / invoked_sum_5m) * 100.0 
    AS error_pct_5m
    FROM myservice_summary
    WHERE time > now() - 1d
    [GROUP BY other_tags e.g. vendor_id]

或者采用更表格的格式:

SELECT [vendor_id, etc, ](error_sum_5m / invoked_sum_5m) * 100.0 
    AS error_pct_5m
    FROM myservice_summary
    WHERE time > now() - 1d

在另一个 CQ 中使用存储在 myservice_summary 中的结果是可能的,但我不能 100% 确定避免竞争条件,即如果依赖于 myservice_summary 的 CQ 在填充该度量的查询之前执行怎么办?

希望对您有所帮助。

【讨论】:

【参考方案3】:

InfluxDB 缺乏执行此类操作的分析结构。如果您想坚持使用 influxdb,则必须在外部层中实现它并将数据反馈回 influx。

【讨论】:

以上是关于跨 InfluxDb 指标查询?的主要内容,如果未能解决你的问题,请参考以下文章

InfluxDB 监控指标分析

InfluxDB 监控指标分析

influxdb语句一则:查询某天内的聚合指标

Grafana / InfluxDB 查询具有时间范围的计数器数据

influxdb中的多系列查询

如何在 grafana 仪表板中查询 influxdb 以创建模板变量