Обычный мониторинг сообщает, что сервис уже упал. Я проверил видно ли отказ заранее.
Админ узнает об аварии тогда, когда пользователи уже видят ошибку.
Вопрос ставился иначе. Не «сервер упал», а «сервер упадет через две минуты». Разница в том, что во втором случае еще можно вмешаться, например перерсапределить нагрузку.
И сразу второй вопрос. Допустим, приближение отказа видно в метриках. Нужна ли для этого модель, или хватит правила вида «дескрипторов больше тысячи»? Проект отвечает на оба, и второй ответ оказался важнее первого.
Размеченных отказов я не нашел. Ждать настоящих бессмысленно: за месяц наберется три штуки.
Поэтому аварии воспроизводились сами, по расписанию, на трех отдельных VPS. Пять типов давления, и каждое нарастает несколько минут, а не возникает мгновенно. Иначе было бы нереалистично и предсказывать было бы нечего: между «все хорошо» и «все упало» не осталось бы времени.
Для пользователя страница, которая грузится восемь секунд, сломана так же, как недоступная.
Сначала отказом был только отсутствующий ответ. При таком определении три типа давления из пяти не дали ни одного события: сервис отвечал, пусть и с задержками. Поэтому отказ переопределен: нет ответа или ответ дольше 375 миллисекунд, где 375 это 99-й перцентиль задержки в спокойное время.
Дальше появилась вторая проблема. Около порога задержка колеблется, и одна авария разваливается на пять отдельных событий. Помог гистерезис: вход в отказ по 375 миллисекундам, выход только когда задержка упала ниже 250 и продержалась там примерно полминуты. Тридцать семь сырых переходов определились в тридцать одну настоящую аварию.
Мгновенное значение метрики почти бессмысленно. Значение двигается
Тысяча дескрипторов это норма для одного сервиса и проблема для другого. Поэтому каждая метрика превращается в набор скользящих окон на 30, 60 и 120 секунд, и модель видит не число, а его поведение.
Машина node-2 (одна из тестовых VPS), исчерпание файловых дескрипторов, отказ в 13:35:15. Модель пересекла порог в 13:33:15
Аналог модели простой: fd_allocated > порог. Если он справляется, машинное обучение здесь не нужно.
Чтобы сравнение было честным, оба метода поставлены в одинаковые условия, взятые из Alertmanager. Тревога поднимается, только если условие держится три интервала подряд, и не чаще раза в десять минут на сервер. Без этих условий любой детектор выдаст много срабатываний на одну аварию, и сравнивать будет нечего.
| Показатель | Модель | Правило |
|---|---|---|
| Тревог поднято | 5 | 12 |
| Из них по делу | 4 | 0 |
| Точность | 80 % | 0 % |
| Аварий предупреждено | 4 из 31 | 0 из 31 |
| Среднее упреждение | 108 с | нет |
| Доля пустых тревог | 20 % [3,6 – 62,4] | 100 % [75,8 – 100] |
В скобках доверительные интервалы. При пяти и двенадцати наблюдениях доказать обычно нельзя ничего, но здесь интервалы не пересекаются: верхняя граница у модели 62,4 процента, нижняя у правила 75,8. Разрыв слишком велик, чтобы это оказалось случайностью выборки.
Правило видит одно число. Модель видит движение сразу нескольких показателей.
Порог по дескрипторам сработал двенадцать раз и ни разу не попал в аварию: на живой машине это число скачет само по себе (откройте диспетчер задач на своем ПК и понаблюдайте). Модель поднимала тревогу в 5 раз реже и попадала в четырех случаях из пяти, потому что смотрит на диск, сеть и память одновременно и на три разных окна усреднения.Случайное разбиение здесь было бы утечкой, так как соседние точки ряда почти одинаковы.
Обучение происходило на прошлом, а проверка на будущем. И отдельно проверка на машине, которую модель никогда не видела - учимся на двух, проверяемся на третьей. Это отвечает на вопрос, заработает ли система на новом для нее сервере.
Названная слабость перестает быть уязвимостью.
Система запущена как обычный сервис systemd на боевом контуре: читает метрики из Prometheus, применяет тот же код признаков, что и при обучении, и присылает в Telegram вероятность вместе с тремя главными признаками по SHAP.
Настоящее срабатывание. Адрес машины скрыт.