首页 文章

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

提问于
浏览
7

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

具体来说,我正在使用:

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

根据influxdb docs non-negative-derivative

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

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

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

perSecond(consolidateBy(my_counter, 'max'))

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

2 回答

  • 12

    如果你想要每秒钟的结果,那么't vary, you'想要 GROUP BY time(1s) . 这将为您提供准确的 perSecond 结果 .

    请考虑以下示例:

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

    0s → 1s → 2s → 3s → 4s
    1  → 2  → 5  → 8  → 11
    

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

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

    0s-2s   →    2s-4s
    (5-1)/2  →  (11-5)/2
       2     →      3
    

    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
    

    解决

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

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

    确切的等式是

    ∆y/(∆x/tu)
    

    考虑我们将事物分组为 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
    

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

    如果我们对 2s 桶的情况应用类似的推理,其衍生区间为 2s ,那么

    0s-2s     →    2s-4s
    2*(5-1)/2  →  2*(11-5)/2
       4       →      6
    

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

  • 3

    @ Michael-Desa给出了很好的解释 .

    我想通过解决我们公司感兴趣的一个非常常见的指标来增加答案:“特定测量领域的 maximum "operation per second"值是多少?” .

    我将使用我们公司的真实案例 .

    场景背景

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

    • TipTrgUp - >业务触发器更新(存储过程)

    • TipTrgRm - >通过业务触发器(存储过程)删除

    • TipRprUp - >通过无人参与的自动修复批处理进行更新

    • TipRprRm - >通过无人参与的自动修复批处理进程删除

    • TipDmpUp - >批量转储过程的更新

    我们制作了一个度量收集器,它将这些计数器的当前状态发送到InfluxDB,间隔为1秒(可配置) .

    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)
    

    附注: $rp 是保留政策的名称,以grafana模板化 . 我们使用CQ来缩减采样到具有更长持续时间的保留策略 . 另请注意 1s 作为派生参数:它是必需的,因为使用GROUP BY时默认值不同 . 在InfluxDB文档中很容易忽略这一点 .

    24小时看到的图表如下所示:
    enter image description here

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

    Grafana图2:低分辨率和高分辨率,真正的最大操作,性能低下

    但是我们可以使用 subqueries 将真正的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)
    

    给:
    enter image description here

    Grafana图3:低分辨率和高分辨率,真正的最大操作,高性能,通过CQ预先计算

    我们对这些度量的最终解决方案(但仅当我们需要实时视图时,子查询方法适用于ad-hoc图表)是:使用连续查询预先计算真实的maxops . 我们生成这样的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
    

    从这里开始,在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)
    

    给:
    enter image description here

    放大到1s精度时,您可以看到图形变得相同:
    enter image description here

    希望这有帮助,TW

相关问题