如何使用Influxdb non_negative_derivative获得一致的值?

Ben*_*Ben 11 influxdb grafana

使用grafana和Influxdb,我试图显示一些计数器的每秒速率.如果我使用该non_negative_derivative(1s)函数,则速率的值似乎会根据grafana视图的时间宽度而发生显着变化.我正在使用last选择器(但也可以使用max哪个是相同的值,因为它是一个计数器).

具体来说,我正在使用:

SELECT non_negative_derivative(last("my_counter"), 1s) FROM ...

根据Influxdb docs非负导数:

InfluxDB计算按时间顺序的字段值之间的差异,并将这些结果转换为每单位的变化率.

所以对我来说,这意味着在扩展时间视图时给定点的值不应该改变那么多,因为值应该是每单位的变化率(在我上面的示例查询中是1s).

在石墨中,它们具有特定的perSecond功能,效果更好:

perSecond(consolidateBy(my_counter, 'max'))

关于上面的涌入查询我做错了什么想法?

Mic*_*esa 21

如果您希望每秒的结果不变,那么您需要GROUP BY time(1s).这将为您提供准确的perSecond结果.

请考虑以下示例:

假设每秒计数器的值都这样改变

0s ? 1s ? 2s ? 3s ? 4s
1  ? 2  ? 5  ? 8  ? 11
Run Code Online (Sandbox Code Playgroud)

根据我们对上述序列进行分组的方式,我们会看到不同的结果.

考虑我们将事物分组到2s桶中的情况.

 0s-2s   ?    2s-4s
(5-1)/2  ?  (11-5)/2
   2     ?      3
Run Code Online (Sandbox Code Playgroud)

1s水桶相比

 0s-1s  ?  1s-2s  ?  2s-3s  ?  3s-4s
(2-1)/1 ? (5-2)/1 ? (8-5)/1 ? (11-8)/1
   1    ?    3    ?    3    ?    3
Run Code Online (Sandbox Code Playgroud)

解决

所以对我来说,这意味着在扩展时间视图时给定点的值不应该改变那么多,因为值应该是每单位的变化率(在我上面的示例查询中是1s).

rate of change per unit是一个归一化因子,与GROUP BY时间单位无关.当我们更改导数间隔时,解释我们之前的示例2s可能会提供一些见解.

确切的等式是

?y/(?x/tu)
Run Code Online (Sandbox Code Playgroud)

考虑我们将事物分组到1s派生间隔为的桶中的情况2s.我们应该看到的结果是

 0s-1s    ?  1s-2s    ?  2s-3s    ?  3s-4s
2*(2-1)/1 ? 2*(5-2)/1 ? 2*(8-5)/1 ? (11-8)/1
   2      ?    6      ?    6      ?    6
Run Code Online (Sandbox Code Playgroud)

这可能看起来有点奇怪,但是如果你考虑一下它说什么应该有意义.当我们指定2s我们要求的衍生区间时,该区2s的变化率是多少1s GROUP BY.

如果我们将类似的推理应用于2s具有导数区间的桶的情况2s那么

 0s-2s     ?    2s-4s
2*(5-1)/2  ?  2*(11-5)/2
   4       ?      6
Run Code Online (Sandbox Code Playgroud)

我们在这里要求的是桶的变化率,第一个区间的2s变化率是多少,第二个区间是变化率.2s GROUP BY2s42s6


Tw *_*ert 6

@ Michael-Desa提供了一个很好的解释。

我想通过一种解决我们公司感兴趣的通用指标的解决方案来扩大这个答案:“ 特定测量字段的最大 “每秒操作”值是多少?”。

我将使用我们公司的真实示例。

场景背景

我们将大量数据从RDBMS发送到Redis。传输数据时,我们会跟踪5个计数器:

  1. TipTrgUp ->通过业务触发器进行更新(存储过程)
  2. TipTrgRm ->通过业务触发器删除(存储过程)
  3. TipRprUp ->通过无人值守的自动修复批处理过程进行更新
  4. TipRprRm ->通过无人值守的自动修复批处理删除
  5. TipDmpUp ->通过批量转储过程进行更新

我们制作了一个指标收集器,以1秒的时间间隔(可配置)将这些计数器的当前状态发送到InfluxDB。

Grafana图1:低分辨率,没有真正的最大操作数

这是有用的grafana查询,但在缩小时不会显示真实的最大操作数(我们知道在正常工作日不会发生特别的转储或维护时,它将达到约500个操作数-否则会进入千):

SELECT
    non_negative_derivative(max(TipTrgUp),1s) AS "update/TipTrgUp"
   ,non_negative_derivative(max(TipTrgRm),1s) AS "remove/TipTrgRm"
   ,non_negative_derivative(max(TipRprUp),1s) AS "autorepair-up/TipRprUp"
   ,non_negative_derivative(max(TipRprRm),1s) AS "autorepair-rm/TipRprRm"
   ,non_negative_derivative(max(TipDmpUp),1s) AS "dump/TipDmpUp"
FROM "$rp"."redis_flux_-transid-d-s"
WHERE
    host =~ /$server$/
    AND $timeFilter
GROUP BY time($interval),* fill(null)
Run Code Online (Sandbox Code Playgroud)

旁注:$rp是保留策略的名称,以grafana为模板。我们使用CQ对持续时间较长的保留策略进行下采样。另请注意1s作为衍生参数:它是必需的,因为使用GROUP BY时默认值不同。在InfluxDB文档中,可以轻易忽略这一点。

在24小时内看到的图表如下所示: 在此处输入图片说明

如果我们仅使用1s分辨率(如@ Michael-Desa所建议),则大量数据将从influxdb传输到客户端。它工作得相当好(大约10秒),但对我们来说太慢了。

Grafana图2:低分辨率和高分辨率,真正的最大运算,缓慢的性能

但是,我们可以使用子查询将真实的maxops添加到该图中,这是一个轻微的改进。传输给客户端的数据要少得多,但是InfluxDB服务器必须进行大量的数字运算。B系列(maxops在别名之前):

SELECT
    max(subTipTrgUp) AS maxopsTipTrgUp
   ,max(subTipTrgRm) AS maxopsTipTrgRm
   ,max(subTipRprUp) AS maxopsRprUp
   ,max(subTipRprRm) AS maxopsTipRprRm
   ,max(subTipDmpUp) AS maxopsTipDmpUp
FROM (
    SELECT
        non_negative_derivative(max(TipTrgUp),1s) AS subTipTrgUp
       ,non_negative_derivative(max(TipTrgRm),1s) AS subTipTrgRm
       ,non_negative_derivative(max(TipRprUp),1s) AS subTipRprUp
       ,non_negative_derivative(max(TipRprRm),1s) AS subTipRprRm
       ,non_negative_derivative(max(TipDmpUp),1s) AS subTipDmpUp
    FROM "$rp"."redis_flux_-transid-d-s"
    WHERE
        host =~ /$server$/
        AND $timeFilter
    GROUP BY time(1s),* fill(null)
)
WHERE $timeFilter
GROUP BY time($interval),* fill(null)
Run Code Online (Sandbox Code Playgroud)

给出: 在此处输入图片说明

Grafana图3:低分辨率和高分辨率,真正的最大运算,高性能,由CQ预先计算

我们针对此类指标的最终解决方案(但仅当需要实时视图时,子查询方法才可用于即席图表):使用连续查询来预先计算真实最大值。我们生成如下的CQ:

CREATE CONTINUOUS QUERY "redis_flux_-transid-d-s.maxops.1s"
ON telegraf
BEGIN
    SELECT
        non_negative_derivative(max(TipTrgUp),1s) AS TipTrgUp
       ,non_negative_derivative(max(TipTrgRm),1s) AS TipTrgRm
       ,non_negative_derivative(max(TipRprUp),1s) AS TipRprUp
       ,non_negative_derivative(max(TipRprRm),1s) AS TipRprRm
       ,non_negative_derivative(max(TipDmpUp),1s) AS TipDmpUp
    INTO telegraf.A."redis_flux_-transid-d-s.maxops"
    FROM telegraf.A."redis_flux_-transid-d-s"
    GROUP BY time(1s),*
END
Run Code Online (Sandbox Code Playgroud)

从这里开始,在grafana中使用这些maxops测量很简单。当向下采样到保留时间更长的RP时,我们再次将其max()用作选择器功能。

B系列(.maxops别名中附加)

SELECT
    max(TipTrgUp) AS "update/TipTrgUp.maxops"
   ,max(TipTrgRm) AS "remove/TipTrgRm.maxops"
   ,max(TipRprUp) as "autorepair-up/TipRprUp.maxops"
   ,max(TipRprRm) as "autorepair-rm/TipRprRm.maxops"
   ,max(TipDmpUp) as "dump/TipDmpUp.maxops"
FROM "$rp"."redis_flux_-transid-d-s.maxops"
WHERE
    host =~ /$server$/
    AND $timeFilter
GROUP BY time($interval),* fill(null)
Run Code Online (Sandbox Code Playgroud)

给出: 在此处输入图片说明

当放大到1s精度时,您可以看到图形变得相同: 在此处输入图片说明

希望这会有所帮助,TW