首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用进水数据库non_negative_derivative获得一致的值?

如何使用进水数据库non_negative_derivative获得一致的值?
EN

Stack Overflow用户
提问于 2016-06-24 14:40:17
回答 3查看 19.1K关注 0票数 18

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

具体来说,我用的是:

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

根据非负导数

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

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

在石墨中,它们具有特定的perSecond功能,这一功能要好得多:

perSecond(consolidateBy(my_counter, 'max'))

对于上面的“流入”问题我做错了什么,有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-24 16:55:42

如果您希望每秒的结果不变,您将需要GROUP BY time(1s)。这将给出准确的perSecond结果。

请考虑以下示例:

假设计数器的值在每秒钟都会发生如下变化

代码语言:javascript
复制
0s → 1s → 2s → 3s → 4s
1  → 2  → 5  → 8  → 11

根据我们对以上序列的分组方式,我们将看到不同的结果。

考虑一下将事物分组到2s桶中的情况。

代码语言:javascript
复制
 0s-2s   →    2s-4s
(5-1)/2  →  (11-5)/2
   2     →      3

相对于1s水桶

代码语言:javascript
复制
 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时,解释前面的示例可能会提供一些见解。

精确的方程是

代码语言:javascript
复制
∆y/(∆x/tu)

考虑这样的情况:我们将事物分组到1s桶中,其派生区间为2s。我们应该看到的是

代码语言:javascript
复制
 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的导数区间时,我们要求的是1s GROUP BY桶的2s变化率。

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

代码语言:javascript
复制
 0s-2s     →    2s-4s
2*(5-1)/2  →  2*(11-5)/2
   4       →      6

我们在这里要求的是,2s变化率是2sGROUP BY桶,在第一个区间,2s变化率是4,第二个区间,2s变化率是6

票数 32
EN

Stack Overflow用户

发布于 2017-04-04 07:32:53

@Michael给出了一个很好的解释。

我想用一个我们公司感兴趣的通用度量的解决方案来补充这个答案:“maximum”操作每秒“特定测量字段上的值是什么?”

我会用我们公司的一个真实的例子。

情景背景

我们将大量数据从关系数据库系统发送到雷迪斯。在传输数据时,我们跟踪5个计数器:

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

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

Grafana图1:低分辨率,没有真正的最大运算量

下面是一个有用的grafana查询,但是当放大时没有显示出真正的最大操作(我们知道在一个正常的工作日,当没有特殊的转储或维护发生时,它会转到大约500个操作点,否则就会变成数千个):

代码语言:javascript
复制
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)

Sidenotes:$rp是保留策略的名称,在grafana中模板。我们使用CQ来降低持续时间更长的保留策略。还请注意1s作为一个派生参数:它是必需的,因为在使用GROUP时,缺省值是不同的。这在InfluxDB文档中很容易被忽略。

在24小时内看到的图表如下:

如果我们只使用1s的分辨率(正如@Michael所建议的那样),那么大量的数据就会从进水数据库传输到客户端。它运行得相当好(大约10秒),但对我们来说太慢了。

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

但是,我们可以使用子查询向这个图添加真正的最大值,这是一个小小的改进。向客户端传输的数据要少得多,但是InfluxDB服务器必须进行大量的数字处理。系列B(在别名中加上maxops ):

代码语言:javascript
复制
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)

给予:

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

我们对这类度量的最后解决方案(但只有当我们需要一个实时视图时,子查询方法对即席图很有效)是:使用连续查询预先计算出真正的最大值。我们生成的CQ是这样的:

代码语言:javascript
复制
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 )

代码语言:javascript
复制
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)

给予:

当缩放到1s精度时,您可以看到图形变得相同:

希望这有帮助,TW

票数 9
EN

Stack Overflow用户

发布于 2019-04-14 14:53:26

这里的问题是,根据您在Grafana中查看的时间框架,$__interval宽度会发生变化。

获得一致结果的方法是从每个间隔(mean()median()max()都同样工作)取一个样本,然后通过derivative($__interval)进行转换。这样,当你放大/缩小时,你的导数就会改变来匹配你的间隔长度。

因此,您的查询可能如下所示:

代码语言:javascript
复制
SELECT derivative(mean("mem.gc.count"), $__interval) FROM "influxdb"
WHERE $timeFilter GROUP BY time($__interval) fill(null)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38016051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档