ML-обнаружение аномалий в Zabbix: три месяца в продуктиве, честный отчёт
Подключили внешний ML-сервис обнаружения аномалий к Zabbix. Три месяца в проде: сколько ложных срабатываний, сколько реальных проблем поймано раньше порогового алерта.
Зрелость AIOps-инструментов обнаружения аномалий для российских мониторинговых платформ
Три месяца назад мы подключили ML-сервис обнаружения аномалий к Zabbix на одном из клиентских периметров. Клиент - среднего размера производственная компания, около ста хостов в мониторинге, несколько тысяч метрик. До этого жили на классических пороговых алертах: exceeded threshold - alert, ниже - тишина. Захотели попробовать, можно ли ловить проблемы раньше, пока они ещё не стали инцидентом.
Сейчас есть три месяца данных. Пишем по-честному.
Как устроена схема
Zabbix собирает метрики штатно. Рядом крутится внешний сервис - отдельный Python-процесс с prophet и несколькими простыми детекторами на базе z-score и скользящего среднего. Сервис подтягивает исторические данные через Zabbix API, строит модели по каждой метрике на скользящем окне, и если текущее значение отклоняется от прогноза выше порога - генерирует событие. Это событие уходит обратно в Zabbix через его же API как проблема с кастомным тегом anomaly_ml, а дальше штатная логика нотификаций Zabbix делает своё дело.
Никакой магии: берёшь временной ряд, строишь модель нормального поведения, сравниваешь текущее с ожидаемым. Разница - в том, что «нормальное поведение» учитывает сезонность (дневную, недельную), тренд и историческую вариативность метрики. Порог задаётся не в абсолютных единицах, а в сигмах отклонения от прогнозного коридора.
Три месяца: цифры и ощущения
Начнём с неудобного. Первые три недели ложных срабатываний было много - больше, чем полезных сигналов. Модели строились на коротком окне истории, сезонность ещё не устоялась, и детектор орал на всё подряд: плановые бэкапы ночью, легитимные пики нагрузки по расписанию, регламентные обновления. Дежурные быстро научились игнорировать тег anomaly_ml - что само по себе диагноз.
Мы откатились и потратили ещё две недели на разметку: какие паттерны считать нормальными, где нужны exclusion windows, каким метрикам вообще нет смысла строить ML-модель (булевые статусы, счётчики ошибок с редкими ненулевыми значениями - для них классический threshold работает лучше). После этой итерации сигнал/шум стал приемлемым.
За оставшиеся примерно полтора месяца - несколько наблюдений:
-
Реальных проблем, пойманных раньше порогового алерта, было несколько. Самый показательный случай - деградация дисковой подсистемы на одном из серверов. Латентность I/O начала медленно ползти вверх, ещё не достигнув порога, который мы выставили для классического алерта. ML-детектор поймал отклонение от недельного паттерна примерно за два часа до того, как сработал бы пороговый алерт. За эти два часа инженер посмотрел диск, нашёл начало деградации и спланировал замену без авариного окна.
-
Ложных срабатываний после настройки стало значительно меньше, но не ноль. Регулярно прилетает что-то типа «аномально низкая нагрузка на CPU в воскресенье утром» - потому что кто-то из пользователей взял отгул и его рабочая нагрузка пропала. Технически это аномалия, практически - не проблема. Такие события мы сейчас просто подавляем через теги, но это ручная работа.
-
Некоторые метрики модель так и не научилась нормально предсказывать. Сетевой трафик на одном из шлюзов слишком хаотичен - там нет выраженной сезонности, зато есть крупные непредсказуемые пики. Детектор на этой метрике либо кричит на каждый пик, либо, если ослабить порог, пропускает реальные всплески. Оставили там классический threshold.
Что оказалось сложнее, чем казалось
Первое - управление моделями. Когда метрик несколько тысяч, нельзя смотреть на каждую модель руками. Нужна какая-то автоматическая оценка качества: насколько хорошо модель описывает исторические данные, нет ли drift-а. У нас этого пока нет - делаем периодические выборочные проверки. Это узкое место.
Второе - изменения в инфраструктуре ломают модели. Переехали сервис на другое железо, добавили шардирование БД, поменяли расписание задач - и модель начинает бить тревогу, потому что новое нормальное поведение отличается от того, на чём она обучалась. Каждое такое изменение требует либо переобучения модели, либо принудительного exclusion window. В реальной инфраструктуре такие изменения происходят регулярно.
Третье - доверие команды. Это не техническая проблема, но реальная. После первых трёх недель с шумными ложными срабатываниями дежурные стали относиться к anomaly_ml событиям со скепсисом. Восстанавливать доверие пришлось медленно - объяснять каждый хороший сигнал, разбирать каждое ложное. Если запускать снова, я бы начал с очень небольшого числа метрик, где уверен в модели, и постепенно расширял охват.
Где это реально работает
По итогам трёх месяцев у нас есть список метрик, где ML-детектор работает хорошо и где мы ему доверяем: дисковые латентности, потребление памяти с выраженным суточным паттерном, время ответа приложений с предсказуемой нагрузкой. Именно на этих метриках он несколько раз отработал раньше классических алертов.
Есть список метрик, где он не работает и куда мы его убрали. Есть большая серая зона, где мы ещё не приняли решение.
Итог пока промежуточный: инструмент работает, но не как серебряная пуля и не «из коробки». Настройка, разметка нормального поведения, управление exclusion windows - это реальная операционная работа, которую кто-то должен делать. Если это делать, инструмент даёт ценность. Если запустить и забыть - получите шумный детектор, которому никто не верит.
Для тех, кто занимается managed-сопровождением инфраструктуры: тема интересная и мы продолжаем эксперимент. По итогам следующего квартала будет больше данных о том, какие классы метрик стоит отдавать ML, а какие лучше оставить на классических порогах.
- Ansible Automation Platform 2.5: смотрим на Event-Driven Ansible для реакции на инциденты Zabbix · 13 февраля 2025
- LLM-агент на IT-хелпдеске: первый месяц в проде · 30 января 2025