Как получить непротиворечивые значения с помощью influenxdb non_negative_derivative?

Используя графану с притоком, я пытаюсь показать частоту в секунду некоторого значения, которое является счетчиком. Если я используюnon_negative_derivative(1s) В зависимости от ширины графического представления значение функции, по-видимому, резко меняется. Я используюlast селектор (но также может использоватьmax это то же значение, так как это счетчик).

В частности, я использую:

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

СогласноInspxDB документы неотрицательно-производные:

InfluxDB рассчитывает разницу между значениями хронологического поля и преобразует эти результаты в скорость изменения на единицу.

Так что для меня это означает, что значение в данной точке не должно сильно меняться при расширении представления времени, так как значение должно бытьскорость изменения на единицу (1 в моем примере запроса выше).

В графите они имеют специфическуюperSecond функция, которая работает намного лучше:

perSecond(consolidateBy(my_counter, 'max'))

Любые идеи о том, что я делаю не так с запросом притока выше?

Ответы на вопрос(2)

Решение Вопроса

Если вы хотите, чтобы результаты в секунду не менялись, вам нужно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

адресация

Так что для меня это означает, что значение в данной точке не должно сильно меняться при расширении представления времени, так как значение должно быть скоростью изменения на единицу (1 в моем примере запроса выше).

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 GROUP BY ведро.

Если мы применим аналогичные рассуждения к случаю2s ведра с производным интервалом2s затем

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

То, что мы просим здесь, это то, что2s скорость изменения для2s GROUP BY ведро и в первом интервале2s скорость изменения будет4 и второй интервал2s скорость изменения будет6.

@ Майкл-Деса дает отличное объяснение.

Я хотел бы дополнить этот ответ решением довольно распространенного показателя, который интересует наша компания: «Что такоемаксимальная значение операции в секунду для определенного поля измерения?

Я буду использовать реальный пример из нашей компании.

Сценарий Фон

Мы отправляем много данных из РСУБД вRedis, При передаче этих данных мы отслеживаем 5 счетчиков:

TipTrgUp -> Обновления по бизнес-триггеру (хранимая процедура)TipTrgRm -> Удаляет бизнес-триггером (хранимая процедура)TipRprUp -> Обновления автоматическим восстановлением в пакетном режимеTipRprRm -> Удаляет в автоматическом режиме пакетного восстановления автоTipDmpUp -> Обновления в процессе массового дампа

Мы создали сборщик метрик, который отправляет текущее состояние этих счетчиков в InfluxDB с интервалом в 1 секунду (настраивается).

Графана График 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)

Sidenotes:$rp это название политики хранения, созданной в графане. Мы используем CQ для уменьшения количества политик хранения с большей продолжительностью. Также обратите внимание на1s в качестве производного параметра: это необходимо, поскольку по умолчанию используется другое значение при использовании GROUP BY. Это может быть легко пропущено в документации InfluxDB.

График за 24 часа выглядит так:

Если мы просто используем разрешение в 1 с (как предложено @ Michael-Desa), огромное количество данных передается с притока на клиент. Это работает достаточно хорошо (около 10 секунд), но слишком медленно для нас.

График Grafana 2: низкое и высокое разрешение, истинный максимум операций, низкая производительность

Однако мы можем использоватьподзапросы добавить настоящие максимальные значения к этому графику, что является небольшим улучшением. Клиенту передается намного меньше данных, но серверу 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)

дает:

График Графана 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

С этого момента, это просто использовать эти измерения мопс в графане. При понижении частоты до 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)

дает:

При увеличении с точностью до 1 с вы можете видеть, что графики становятся идентичными:

Надеюсь, это поможет, TW

Ваш ответ на вопрос