LINUX.ORG.RU

Подсчет потерь (алгоритм)?

 


0

2

Приветствую.

Нуждаюсь в идеи )

Сцуть - есть 100500 железок в интернетах, которые раз в 10-15 минут опрашиваются, в БД в поле отправленных запросов пишу +1, когда ответ приходит (снимок) в БД в поле полученных ответов пишу +1 и дата-время последнего ответа

Вопрос - как посчитать АКТУАЛЬНОЕ количество потерь в % скажем за 10 или 100 опросов??? так чтобы не плодить количество записей

★★★

Последнее исправление: Dimez (всего исправлений: 2)

Где-то должна быть табличка с временем ответа для каждого типа железки. Тогда можно экстраполировать идеальную ситуацию для периода и сравнить с реальной. Ты же понимаешь, что процент потерь можно посчитать только за заданный период? Ну и естественно в табличке с ответами должен быть таймштамп ответа.

faq2
()
Ответ на: комментарий от faq2

да можно писать время запросов и время ответов, но это ж звездец сколько записией!!! вон top же как то считает нагрузку за 5/10/15 последних минут, в принципе мне похожее и надо, только для потерь

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

в принципе мне похожее и надо, только для потерь

В ОП очень непонятно всё описано. Так-то считаешь за период дельту счетчика запросов и дельту счетчика ответов, вот тебе и процент потерь успешных запросов. Или, если нет счетчиков, то просто количество запросов и количество ответов за период.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 3)
Ответ на: комментарий от vvn_black

ну так для этой дельты придется 100500 * на количество на интервале надо записей хранить для подсчета текущих чисел. а потом еще с каким то интервалом пересчитывать всю эту гору дат

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 3)

Заведи два счётчика в БД - пoлнoе кoличествo oпрoсoв (+1 каждый oтправленный запрoс) и кoличествo oтветoв за интересующий интервал (+1 каждый пoлученный oтвет). И кoгда пoлнoе кoличествo oпрoсoв делится без oстатка на 10 или 100, тo втoрая кoлoнка oбнуляется, нo предварительнo её значение как вещественнoе делится на 10 или 100 и вывoдится юзеру (или сoхраняется в третью кoлoнку) как прoцент успеха (а если вычесть этo числo из единицы, тo пoлучится прoцент пoтерь).

Если все железки oпрашиваются oднoвременнo, тo вместo первoй кoлoнки хватит глoбальнoгo счётчика. Если oпрoс идёт пo времени, например, 100 oпрoсoв в сутки, тo мoжнo прoстo в пoлнoчь (или другoй мoмент времени пo таймеру) забирать значение счётчика oтветoв и oбнулять егo.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от wolverin

Так-то, нужны две таблицы, одна с запросами, вторая с ответами и записи в них с id железок. Можно хранить только записи за последний час, например. Ну это так, навскидку, без глубоких размышлений. )

vvn_black ★★★★★
()

Совсем не плодить не выйдет, придётся добавить чуть полей. И потери будут не за чёткий интервал, а примерно-усренённые.

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

Отправка:

  if(waiting) { loss10+=SCALE; loss100+=SCALE; }
  loss10 -= loss10/10;
  loss100 -= loss100/100;
  waiting = 1;

Пришёл ответ:

  waiting = 0;

SCALE - либо ставишь 1 и хранишь loss10 и loss100 как числа с плавающей точкой, либо SCALE=1000 и хранишь loss10/loss100 как целые числа.

В переменных loss10/SCALE и loss100/SCALE будут усреднённые потери за примерно 10 и примерно 100 последних опросов. Примерно - потому что на самом деле оба числа будут учитывать намного больше последних опросов, но если недавняя потеря добавит к ним единицу, то потеря, случившаяся 10/100 опросов назад добавит уже величину 0.36, а потеря, случившаяся 20/200 опросов назад добавит всего 0.13 (за каждые 10/100 опросов «вес» потери падает в 2.7 раз). Если не нужна 100% строгость то такой подход обычно вполне адекватные числа даёт.

Если хочешь именно строго за последние 10/100 - то вариант только один - хранить все ответы за интересующий интервал.

firkax ★★★★★
()
Ответ на: комментарий от wolverin

проще говоря - есть уровень сигнала в телефоне - как только он упал ниже условно 50% - шлем алярму человеку сразу, а не через ручной интервал

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

вы же смотрите нагрузку в top не через любое время

Там avg - средние значения, просто селекты делаешь за последние 5/10/сколько надо минут.

Т.е. запись такая - тайштамп, id железки. И селекты последних записей с отсечкой по времени назад.

vvn_black ★★★★★
()
Ответ на: комментарий от wolverin

нет никакой ошибки ответа, запрос послали, а ответят или нет не известно.

Любое IO генерирует ошибки. Да и ошибка это достаточно абстрактное понятие, что позволяет под ошибкой понимать и отсутствие ответа.

urxvt ★★★★★
()
Ответ на: комментарий от wolverin

да можно писать время запросов и время ответов, но это ж звездец сколько записией!!! вон top же как то считает нагрузку за 5/10/15 последних минут, в принципе мне похожее и надо, только для потерь

man procfs:

/proc/loadavg

The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) averaged over 1, 5, and 15 minutes. They are the same as the load average numbers given by uptime(1) and other programs. The fourth field consists of two numbers separated by a slash (/). The first of these is the number of currently runnable kernel scheduling entities (processes, threads). The value after the slash is the number of kernel scheduling entities that currently exist on the system. The fifth field is the PID of the process that was most recently created on the system.

$ cat /proc/loadavg 
0.59 0.53 0.54 3/131 538
AlexVR ★★★★★
()

я придумал такой алгоритм: запросы складываешь как раньше, то есть +1 на каждый запрос, а ответы складываешь в массива длиной log2(n), где n - максимальное количество опросов, потери которых хочешь считать.

для каждого бита в request_counter складываешь ответы из следующей ячейки массива и текущей и кладёшь в следующую, если бит равен 1, или просто добавляешь ответы к текущей, если бит равен 0. при «переполнении» массива кладёшь переполненное в общую корзинку.

я уверен, что ничего толком не понятно из того, что я написал, но могу заверить, что при n=10 ты сможешь выводить статистику по последним записям вплоть до 1024 штук)

anonymous
()

Приветствую.

Нуждаюсь в идеи )

в БД в поле отправленных запросов пишу +1, когда ответ приходит (снимок) в БД в

поле полученных ответов пишу +1 и дата-время последнего ответа

Вопрос - как посчитать АКТУАЛЬНОЕ количество потерь в % скажем за 10 или 100 опросов???

Примерно я бы делал как то так:

SELECT count(поле_запроса) - SELECT count(поле_ответа)

WHERE (поля_запроса) IS NOT NULL 
Ygor ★★★★★
()
Ответ на: комментарий от urxvt

urxvt

Любое IO генерирует ошибки.

нет, типа асинхронные запросы - туда запрос, обратно событие, может быть, может нет.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от firkax

firkax

Если хочешь именно строго за последние

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

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от anonymous

а не, фигня какая-то, при request_counter = 0x100, например, все суммы скопятся в 9-й ячейке массива и узнать статистику можно будет минимум только за последние 256 запросов.

anonymous
()
Ответ на: комментарий от urxvt

urxvt

)) кого ее? ну есть у посылки на сервер через mqtt информация об успешности отправки, а мне нужно ЖЕЛЕЗКУ проверить которая подписана на топик mqtt сервера, так понятнее???

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

)) кого ее?

Ошибки.

ну есть у посылки на сервер через mqtt информация об успешности отправки,

А если отправка не успешна, то в результате мы получаем... Громче, пожалуйста.

Но, главное, ты не понял, что я имел ввиду — отсутствие ответа это тоже ошибка.

urxvt ★★★★★
()

а что, если хранить статус ответа в битиках?

uint64_t b[4];
for (int i=sizeof(b)/8-1; i>0; i--) {
    b[i] = (b[i] << 1) + (b[i-1]>>63);
}
b[0] = (b[0] << 1) + status;

и считать битики через popcount, предварительно занулив нужное количество.

и быстро и точно и хранить не напряжно.

anonymous
()
Ответ на: комментарий от wolverin

Я не понял что ты откуда собрался отнимать, но честную скользящую статистику без сохранения полной истории за последние N запросов сделать невозможно. Приблизительную скользящую можно - я описал как.

firkax ★★★★★
()
Ответ на: комментарий от urxvt

Всё он понял и правильно тебе ответил. Ты предлагал создавать запись по факту отсутствия ответа, а у него за наличием ответа никто не следит. То есть событие есть только если ответ произошёл, а если ответа не случилось - то никто ничего не делает.

Единственное что он не догадался так это то, что отсутствие ответа можно фиксировать при отправке следующего запроса. Но всё равно, у него в условии задачи не плодить переменные, а ты хочешь на каждый из как минимум 100 запросов что-то сохранять.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Напомню что я предлагал.

А не лучше ли делать запись (новую строку) при получении/ошибке ответа?

Предлагал я делать запись не перед отправкой запроса и потом обновлять флаг успешного получения ответа, а делать это единожды в конце. Чтобы не перечислять (и вообще о них не заботиться) все возможные варианты развития событий (IO error, memory allocation error, timeout, etc) я их все назвал ошибками. Ибо в контексте задачи не получение ответа вовремя (timeout) от любой другой ошибки ничем не отличается.

а ты хочешь на каждый из как минимум 100 запросов что-то сохранять.

А как ты будешь собирать статистику не делая запись в хранилище?

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

а делать это единожды в конце

В каком конце? У него отправка делается и ничего больше не ждёт, а приход ответа это отдельное самостоятельное событие. Ветки «мы ждали ответ, но недождались» у него нет.

Ибо в контексте задачи не получение ответа вовремя (timeout) от любой другой ошибки ничем не отличается.

Ну да, он даже не узнает по какой причине не пришёл ответ - то ли запрос не отправился/не дошёл, то ли ответ не вернулся.

А как ты будешь собирать статистику не делая запись в хранилище?

У него как раз суть вопроса в том как именно это и сделать. И это возможно, хотя и не строго по последним N событиям, я даже выше ему написал как.

Хотя может я конечно неправильно понял вопрос, но другого смысла у «не хочу плодить количество записей» я не могу придумать.

firkax ★★★★★
()
Ответ на: комментарий от firkax

В каком конце? У него отправка делается и ничего больше не ждёт, а приход ответа это отдельное самостоятельное событие. Ветки «мы ждали ответ, но недождались» у него нет.

Теперь ясно. Из его описания это никак не следут. Написал бы, что у него две независимые очереди, или куда там ответ приходит.

опрашиваются, в БД в поле отправленных запросов пишу +1, когда ответ приходит

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

А если отправка не успешна, то в результате мы получаем

не успешная отправка запроса не учитывается в уровне потерь

отсутствие ответа это тоже ошибка.

у вас теплое с мягким перемешалось

wolverin ★★★
() автор топика
Ответ на: комментарий от firkax

честную скользящую статистику без сохранения полной истории за последние N запросов сделать невозможно.

да и Бох с ним, нужна лишь достаточно точная оценка при максимальной производительности ее вычисления.

отнимаю я каждый раз -1 из количества успешных ответов при успешной отправке, когда достигается выбранный мной лимит «интервала» скажем в 10 запросов, дальше как обычно вычисления в % «уровня сигнала» - получилось в целом то что надо - скользящая статистика без кучи записей )

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)
Ответ на: комментарий от wolverin

у вас теплое с мягким перемешалось

Рекомендую глянуть на существующие программные интерфейсы (aka API) и подумать, почему во всех (?) признак timeout возвращается как ошибка, а не существует как отдельный тип или отдельное возвращаемое значение.
Прежде можно еще подумать над тем, почему в половине случаев в названии присутствует слово error.

ETIMEDOUT - https://man7.org/linux/man-pages/man3/errno.3.html
TimeoutError — https://docs.python.org/3/library/exceptions.html
SocketTimeoutException — https://docs.oracle.com/javase/8/docs/api/java/net/SocketTimeoutException.html

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

можно сказать на таймауте я первый раз делал сбор «ответов», выяснилось что на большом количестве опрашиваемых железок приводит к деградации всего алгоритма - нельзя сказать точно, что если через какое то время не пришел ответ, он не придет никогда, начинаете ждать ответ непонятное время и не запрашиваете актуальные данные или наоборот - решили что за таймаут ответ не пришел, НО он пришел за большее время.

лучше задумайтесь над тем, что существуют и другие ситуации, требующие других решений.

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

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

urxvt ★★★★★
()
Ответ на: комментарий от scalaris_

запросы шлются и получаются ответы через мктт сервер всем железкам

формула простая - до выбранного лимита увеличиваем счетчики, после достижения счетчик запросов не растет, а уменьшает счетчик ответов - это дает «скользящую» составляющую при том же уровне «чувствительности», остается только 2 вопроса отработать - появление железки на связи (решается сбросом при первом ответе) и улучшения качества связи (решается сбросом каждые N * лимит ответов)

ну и время последнего ответа до кучи для оценки

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)