Как определить, превышает ли скорость события (скользящая средняя) порог - PullRequest
3 голосов
/ 29 мая 2019

РЕДАКТИРОВАТЬ Добавленная информация

Первоначально это было просто об общем алгоритме и не зависит от языка / платформы.Однако я собираюсь ответить на этот вопрос сам, и ответ на самом деле зависит от используемых инструментов.

Это для обнаружения событий на мэйнфрейме IBM в z / OS с использованием средства автоматизации Ops / MVSзапуск сценария REXX.

Таким образом, опубликованные ответы могут быть применимы в Python, Perl, bash, Java и т. д .;просто продукт, который используется в данном конкретном случае, имеет особую функцию, которая делает свое дело.

Конец добавленной информации

Мой вопрос очень похож на этот:

Как рассчитать частоту непрерывных гладких событий на основе времени события?

, и это будет ответом:

Это можно реализоватьс скользящей средней.Возьмите последние N событий, где N - размер окна усреднения.Вычислите разницу во времени между первым и последним из этих N событий.Если вы измеряете в секундах и хотите получить скорость в событии в минуту, то вы поделите 60 секунд на разницу во времени, выраженную в секундах, и умножите на N-1.

, за исключением того, что я хотел быИзбегайте хранения информации о предыдущих событиях.Меня также интересует только, превышает ли скользящее среднее значение пороговое значение, поэтому меня не интересует сохранение тренда курса.

Так, например, я хочу знать, получаю ли я больше 3 событий / мин.,Это был мой первый подход:

  1. Когда приходит первое событие, я создаю счетчик 1 и записываю время начала.
  2. Когда приходит другое событие, я увеличиваю счети вычислите скорость из подсчета и истекшего времени
  3. Если скорость превысит допустимое значение, сгенерируйте предупреждение.

Я понял, что это не сработает, потому что если у вас было событие в неделюназад, а затем ничего до 10 событий в последнюю минуту, средняя «скорость» равна 11 в неделю, то есть 3,6 / день, а не текущая скорость 10 / мин.

Так что я думаю о попыткеследующее:

  1. Когда приходит первое событие, я создаю счет 1 и записываю время начала.
  2. Когда приходит другое событие, если время с момента предыдущего событияпревышает интервал, в течение которого я хочу измерить скорость (1 мин в моем примере), я фактически отбрасываю предыдущее событие и записываю счетчик 1 и текущее время как новое время начала (потому что, если оно прошло более 1 мин с моментаPrevioСША, скорость не может превышать х / мин, верно?).
  3. Если время, прошедшее с момента предыдущего события, не превысило интервал мониторинга, увеличьте счет и рассчитайте скорость на основе подсчета и прошедшего времени.время
  4. Если скорость превысит допустимое значение, создайте оповещение.

Это кажется простым, но другие сообщения о SO (в частности, этот вопрос: Оценка скорости возникновения события с экспоненциальнойсглаживание и нерегулярные события и принятый ответ: https://stackoverflow.com/a/23617678/1430420), похоже, подразумевает, что в этом гораздо больше, чем я думаю.

Ответы [ 2 ]

1 голос
/ 30 мая 2019

Ops / MVS имеет эту функцию, встроенную с помощью функции 'OPSTHRSH':

https://docops.ca.com/ca-opsmvs/13-5/en/reference-information/command-and-function-reference/ops-rexx-built-in-functions/opsthrsh-function

для этого конкретного сценария, мы можем вызвать его следующим образом:

if OPSTHRSH('A',60) > 3 then do something...

OPSTHRESH ('A', 60) вернет счетчик того, сколько раз текущее событие сработало для текущего адресного пространства (задачи) в течение 60-секундного периода.Если это значение превышает мой уровень триггера, примите меры.Через 60 секунд после получения первого события счетчик событий сбрасывается.

0 голосов
/ 29 мая 2019

Используйте следующий псевдокод:

boolean update(long timestamp, History h, int windowSize, int minEventsToTrigger) {
    h.removeOlderThan(timestamp - windowSize);
    h.addEvent(timestamp);
    return h.size() >= minEventsToTrigger;
}

Где h - круговой буфер , хранящий метки времени со следующими операциями:

  • removeOlderThan(t): удаляет все события, которые произошли до t.Эта операция амортизируется O(1), поскольку каждое событие будет удалено ровно один раз, а события (кроме самых старых) никогда не будут запрашиваться более одного раза для удаления.

  • addEvent(t):добавляет событие в конец буфера или, если буфер заполнен, сначала удаляет самое старое событие, а затем добавляет новое событие.Операция O(1);а отказ от старого события для нового гарантирует, что внезапный поток событий не будет перегружать систему, не потребует дополнительной памяти или нарушит этот код - до тех пор, пока minEventsToTrigger меньше, чем емкость h, результаты будутвсегда будь прав.

Этот псевдокод, я считаю, оптимален во времени и, вероятно, также в пространстве.Важно отметить, что он не требует какого-либо динамического выделения.

Функция update возвращает значение true, если при новом событии было получено не менее minEventsToTrigger в пределах windowSize единиц времени или значение false в противном случае,Обратите внимание, что он предназначен для вызова только при получении каждого события и, следовательно, может точно нарастающие фронты (падающие фронты не будут обнаружены до следующего события).Если вы хотите исправить это, у вас есть два варианта:

  • регулярно проводить опрос, чтобы выяснить, перестает ли после вызова h.removeOlderThan(timestamp - windowSize); условие return h.size() >= minEventsToTrigger; выполняться.Это может быть расточительным, если события очень редки;если вы делаете это только при срабатывании оповещения, вы можете сохранить множество ненужных операций.
  • использовать какой-либо механизм таймера, чтобы при срабатывании оповещения просыпаться сразу после наступления самого старого событияистекать.Это гарантировало бы минимальную задержку между истечением срока действия события и проверкой h.size() >= minEventsToTrigger.
...