Anomaly detection в Zabbix 7.0: baseline вместо порогов, и когда это идёт не так
Zabbix 7.0 LTS добавил ML-based anomaly detection как встроенную функцию. Настраиваем baseline для ключевых метрик managed-инфраструктуры и разбираем, когда автопорог мешает.
Zabbix 7.0 LTS и Prometheus/Grafana-стек добавили ML-based anomaly detection как встроенную функцию
Zabbix 7.0 LTS вышел весной, и одна из заявленных фич - встроенный anomaly detection на основе baseline. Не плагин, не внешняя интеграция, а прямо в ядре: алгоритм смотрит на историю метрики и строит «нормальный коридор», за пределами которого триггер срабатывает автоматически. Примерно в то же время Grafana 11 подтянула похожую механику через встроенные трансформации и ML-расширения для Prometheus. Мы занимаемся managed-инфраструктурой для нескольких клиентов, и эту возможность было логично проверить не в демо-среде, а на реальных метриках.
Что такое baseline в Zabbix 7.0
В Zabbix 7.0 функция называется Anomaly detection и включается на уровне элемента данных через отдельный тип preprocessing: ANOMALY_DETECTION. Алгоритм обучается на скользящем окне истории (по умолчанию - 4 недели) и строит сезонный профиль: отдельно для каждого часа суток и дня недели. Результат - «верхняя граница нормы» для каждого момента времени, которая меняется в зависимости от дня и часа.
Это принципиально отличается от статичного порога. Статичный порог для CPU-утилизации, например, выглядит как «алерт при >80%». Baseline говорит «в понедельник в 10 утра нормально до 60%, а в воскресенье ночью нормально до 15% - всё что выше, подозрительно». Для инфраструктуры с нагрузкой, которая меняется в течение дня и недели, это разумнее.
Prometheus/Grafana идёт другим путём: аномалии там считаются через predict_linear и кастомные recording rules, а в Grafana 11 появились экспериментальные ML-функции в виде плагина Machine Learning - он строит forecast и highlight на основе LSTM прямо в дашборде. Мы тестировали оба подхода, но основной кейс - Zabbix, потому что большинство клиентов работает именно на нём.
Что настроили и на каких метриках
Взяли три типа метрик, которые в нашей практике чаще всего вызывают ложные алерты при статичных порогах:
CPU-утилизация на серверах с batch-нагрузкой. У одного клиента ночью по расписанию запускаются ETL-задачи - CPU прыгает до 70-75%, что с классическим порогом в 80% дает минимальный запас и периодические ложные алерты при небольших пиках. Baseline корректно выучил эту ночную нагрузку как норму и перестал шуметь.
Дисковый трафик на storage-нодах Ceph. Паттерн нагрузки у Ceph предсказуем: repbalancing происходит в окна с минимальным клиентским трафиком, обычно ночью. Статичный порог по disk I/O был либо слишком чувствительным днём, либо пропускал реальные проблемы ночью. Baseline справляется заметно лучше.
Latency к внешним API. Это самый нестабильный кейс - об этом ниже.
Технически включение выглядит так: в элементе данных добавляешь preprocessing step ANOMALY_DETECTION, задаёшь окно обучения и чувствительность (параметр sensitivity от 0 до 1, где 1 - максимальная чувствительность). Триггер переписываешь с {host:item.avg(5m)}>80 на {host:item.anomaly()}>0. Всё.
Где автопорог мешает
Ожидали, что это будет магия. Оказалось - полезный инструмент с конкретными ограничениями.
Метрики без устойчивого паттерна. Latency к внешним API у одного клиента зависит от активности их собственных пользователей, которая непредсказуема. Baseline через 4 недели «выучил» какой-то средний профиль, но при реальных проблемах со стороны внешнего провайдера алерт либо запаздывал, либо не приходил вообще - потому что латентность хоть и выросла, но не вышла за дисперсию нормального диапазона. Для таких метрик статичный порог надёжнее.
Плановые работы и разовые события. Если на сервере провели нагрузочный тест или мигрировали базу - baseline «съедает» этот выброс в историю и начинает считать повышенную нагрузку нормой. В Zabbix 7.0 нет встроенного механизма исключить конкретный временной диапазон из обучающей выборки. Мы обходим это костылём: добавляем maintenance period в Zabbix (он всё равно нужен для подавления алертов во время работ), а у одного клиента написали скрипт, который через API Zabbix временно снижает sensitivity элемента до нуля на время плановых работ и возвращает обратно.
Первые 4 недели - слепое пятно. Пока не накоплена история, алгоритм не работает. На новых серверах это означает месяц без anomaly detection - нужно держать параллельный статичный триггер как страховку.
Чувствительность - чёрный ящик. Параметр sensitivity влияет на ширину коридора, но не линейно и не задокументировано с конкретными формулами. Нужная чувствительность подбирается итеративно: поставил 0.7, смотришь неделю, слишком много шума - уменьшаешь до 0.5 и т.д. Это нормально для любого ML-параметра, но осознать это нужно сразу, чтобы не ждать «само настроится».
Как настроили исключения
Два подхода, которые прижились:
Maintenance + API-скрипт. Для плановых работ: за 10 минут до начала скрипт снижает sensitivity затронутых хостов, по окончании - возвращает. Заодно это логируется, и мы видим, когда и почему изменялась настройка.
Гибридный мониторинг. Для метрик без устойчивого паттерна оставили статичный триггер с агрессивным порогом (реагирует на явные выбросы) и добавили baseline как дополнительный сигнал, который идёт не в алерт, а в отдельный дашборд для анализа. Это позволяет видеть тренды без шума в ночных смс.
Где сейчас
Anomaly detection в Zabbix 7.0 работает в продуктиве у двух клиентов - на метриках с предсказуемым паттерном нагрузки. Количество ложных алертов по этим метрикам снизилось ощутимо. Для метрик без паттерна остаёмся на статичных порогах - они предсказуемее.
Prometheus-стек с Grafana ML-плагином пока в тестовом контуре: плагин помечен как experimental, и для managed-инфраструктуры клиентов мы предпочитаем не завязываться на экспериментальные компоненты в ключевых метриках.
Общий вывод после нескольких месяцев работы с этим: baseline работает там, где нагрузка действительно цикличная и хорошо предсказуемая. Для всего остального это не замена ручным порогам, а дополнительный слой поверх них.
- Grafana 11.1 и Scenes API: перекраиваем инфра-дашборды под динамические переменные · 21 августа 2024
- LLM-агенты в ИТ-операциях: запускаем пилот с CodeLlama и Ansible · 26 августа 2024