Собираем 1 000 000 метрик в секунду с сетевых устройств. gNMI.. gNMI. IT-инфраструктура.. gNMI. IT-инфраструктура. NETCONF.. gNMI. IT-инфраструктура. NETCONF. observability.. gNMI. IT-инфраструктура. NETCONF. observability. snmp.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure. коллектор.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure. коллектор. Сетевое оборудование.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure. коллектор. Сетевое оборудование. Сетевые технологии.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure. коллектор. Сетевое оборудование. Сетевые технологии. Системное администрирование.. gNMI. IT-инфраструктура. NETCONF. observability. snmp. Блог компании Yandex Cloud & Yandex Infrastructure. коллектор. Сетевое оборудование. Сетевые технологии. Системное администрирование. телеметрия.
Собираем 1 000 000 метрик в секунду с сетевых устройств - 1

«Бди!» — сказал Козьма Прутков. И действительно, как инженер я считаю важным бдительно следить за показателями сетевых устройств, да и не только сетевых. На связи Александр Балезин из отдела сетевой разработки Yandex Infrastructure. Сегодня расскажу о нашем новом коллекторе метрик с сетевых устройств, о том как мы к нему пришли и о системах вокруг сетевых метрик.

Поделюсь опытом модульного подхода, решениями для поддержки множества брендов устройств и тем, как обеспечить надёжный мониторинг даже в самом сложном сетевом зоопарке. В статье упоминается множество протоколов для мониторинга: если хочется прояснить эту тему, рекомендую почитать АДСМ6

Почему без метрик сетью не управляют

Сетевую инфраструктуру нельзя «держать в голове» и администрировать по ощущениям. Как только появляется масштаб (с большим количеством устройств, вендоров, площадок, сервисов), единственный устойчивый способ понимать, что происходит, — это системно собирать метрики и строить вокруг них процессы.

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

Кроме этого графики можно использовать для capacity planning — экстраполировать исторические данные и понять, что через год какой‑то канал кончится, пора бы его расширять.

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

Например, из‑за высокой нагрузки на CPU роутер начал флапать bgp‑сессиями, из‑за этого терять маршруты и проливать трафик. У нас есть графики утилизации CPU по каждому сервису, и по этим данным видим, что за день до этого очень сильно выросла нагрузка на сервис SNMP, а в это время была выкатка новой версии коллектора метрик. Так вышли сами на себя.

Ну и самое важное применение графиков — это показать на конференции красивые слайды с достижениями.

Желательно, чтобы среди достижений удалось не сойти с ума от количества метрик
Желательно, чтобы среди достижений удалось не сойти с ума от количества метрик

Мониторинг через события и алерты. Глазами все графики не просмотришь: нужно делать событийный мониторинг поверх собранных данных. Начиная от базовых проверок на перегрузки CPU, упавшего линка, низкого уровня сигнала, и заканчивая… Ничем не заканчивая, нет предела разнообразию. События часто ориентируются на несколько метрик, например, реагировать на низкий уровень сигнала нужно только если линк поднят.

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

Выдача данных другим сервисам. Представим, что появился сервис, который хочет получать собранные данные для своих задач. Если задержка не важна и данных немного, то их легко получить из хранилища. Но если данные нужны в огромном объёме и с минимальной задержкой, то такой вариант уже не подходит. Причин несколько: высокая нагрузка на API, никаких гарантий, что получили все данные, — мы забираем их за временное окно, а случиться может и так, что данные придут в предыдущее окно времени. Поэтому мы используем брокер сообщений чтобы давать доступ к данным. Клиенты подписываются на нужные им данные и получают их с минимальной задержкой и в полном объёме.

Примеры таких потребителей: управление сетевой нагрузкой для CDN, сложный алертинг, который невозможно сделать стандартными средствами.

Внутренний типовой workflow выглядит так:

Собираем 1 000 000 метрик в секунду с сетевых устройств - 3

Из брокера данные поступают в хранилище метрик на базе внутренней инсталляции observability‑платформы Yandex Monium. На основе этих метрик строятся дашборды, а рассчитанные алерты передаются в систему обработки событий — «Автотрон».

Подробнее о работе «Автотрона» коллеги рассказывали в своём докладе на nexthop

Подавляющее большинство событий, которые затем обрабатываются, включая инциденты уровня «damage link» (аварии, связанные с физическим повреждением линии связи), берут начало именно здесь — в коллекторе метрик и слое вычисления алертов.

Из истории: как мы пришли к требованиям для коллектора

Эта часть не очень важна, но она показывает эволюцию наших систем и даёт понимание требований к новому коллектору метрик.

Отмотаем время на 2015 год. В это время у нас было две крупных системы для сбора метрик: Сacti и Zabbix. Сacti появился сильно задолго до этого момента и работал как коллектор метрик и рисовалка графиков, Zabbix — то же самое плюс алертинг. Помимо этого Cacti использовался для просмотра карт сети. Для Zabbix была создана автоматика, которая управляла проверками и триггерами по нашей логике и была провязана с нашей системой инвентаризации.

Минусы Сacti — это использование RRDtool, что подразумевает единый интервал шага данных. То есть нельзя для одних устройств оставить пятиминутный интервал, а для других сделать 30 секунд.

Основная сложность с Zabbix была в обслуживании БД: он использовал реляционную базу данных, а не timeseries DB из‑за чего приходилось жонглировать с партиционированием для экономии места. Отказоустойчивость Zabbix была сделана нехитро — две копии в разных дата‑центрах. Одна считалась основной, а вторая — как бы резервной, но отличалась от первой только тем, что не отсылала оповещения. Ещё одной проблемой Zabbix было то, что уходило очень много времени между стартом сервиса и получением всех данных, из‑за чего Network Operations Center оставался без глаз и не мог бдеть.

В это же время у нас активно развивалась система Yandex Monium, пока в качестве внутреннего продукта. Она включала в себя: хранение данных, отрисовку графиков, алертинг. Со временем отношение к данным изменилось — не просто собрать данные, чтобы показать графики, а уметь обрабатывать их, агрегировать, делиться данными с другими сервисами.

Так мы решили написать коллектор. Требование было простое: собрать много метрик по SNMP, передать их в новое хранилище Monium через очередь сообщений, чтобы другие клиенты тоже могли получить данные. Для реализации мы выбрали Python как самый популярный язык в то время в наших кругах, а для декодирования SNMP написали свой декодер на cython.

Перемещаемся в 2024.

За 10 лет с написания поллера стали остро ощущаться недостатки изначального дизайна:

  • Сервис был написан программистами для программистов. По исторической причине добавлением новых видов метрик занимались разработчики системы, поэтому она была сложной для сетевых инженеров.

  • Кроме SNMP стали использовать много других протоколов для сбора: CLI, Netconf, web scrapping. Всё это добавлялось сбоку.

  • Неочевидный процесс обработки данных, так как его часть была в коде и не контролировалась конфигурацией.

  • Сложности с распараллеливанием в Python: приходилось использовать много процессов, что создавало проблемы. Если нужно получить данные со всех процессов (например для отладки), то нужно сводить данные в одно место. Также необходим планировщик процессов, чтобы создавать достаточно процессов под задачи.

  • Сложность в расширении функциональности из‑за архитектуры, не было понятия плагинов.

  • На горизонте маячил gNMI и ожидался сильный рост нагрузки из‑за высокой частоты обновления метрик, а также более тяжелого для декодирования протокола.

Как выбираются метрики

Итак, назрела пора переосмыслить наш подход к коллектору метрик и написать новый‑кленовый коллектор с учётом всех недостатков. Но прежде чем взяться за сам коллектор, опишу наш опыт по выбору того, что и как собирать.

Возьмём самый главный вопрос: какие метрики нужны. Можно выбрать роскошный максимум и собрать вообще все возможные метрики, но с этим есть сложности.

  • Нагрузка на устройства: будет влиять на CPU/память, особенно на слабых устройствах.

  • Хранение и обработка: чем больше метрик — тем больше инфраструктуры под хранение, нужно думать над агрегацией и retention.

  • Сложность первичного внедрения: нужно найти все эти метрики. Если для SNMP есть вариант получить всё, то для других протоколов такого нет, нужно время на исследование. Например, через netconf получаем огромный xml c информацией об интерфейсах, и нужно продумывать, как назвать метрику, как интерпретировать значение: вдруг там строка с именем статуса и нужен маппинг, чтобы в базу положить число. Это титанический труд.

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

Каждая новая поддерживаемая метрика стоит как вычислительных, так и человеческих ресурсов. Поэтому собрать все метрики — недостижимая цель, особенно если у вас в парке множество вендоров.

Подходы к выбору метрик на практике:

  • Исторический. Смотрим, что уже собирается для устройств со схожей ролью. Особенно в случае появления нового вендора.

  • Проактивный. Инженер‑заказчик сам формулирует, что нужно наблюдать. Тут творческий процесс: можно глянуть в документацию, посмотреть, что умеет отдавать устройство, или спросить в техподдержке.

  • Факап‑driven. После аварии стало понятно, какие ещё метрики нужны для событийного мониторинга или хотя бы просто графиков для расследования. Самый частый случай.

    При таком подходе у метрики появляется история возникновения: она появилась не просто так, а потому что случился факап, и она была нужна для расследования, или потому что так захотел заказчик. Если в какой‑то момент получение метрики сломалось, то понятно, у кого спросить, нужна ли она всё ещё.

Чем собирать: SNMP, CLI, NETCONF, gNMI и так далее

Когда понятно, что собирать, возникает вопрос как. Одну метрику можно собрать разными способами. Например, трафик на интерфейсе можно получить через SNMP, netconf, gNMI или даже парсинг вывода CLI‑команды. И каждый из этих способов вендор может реализовать не очень хорошо. Поэтому важно уметь работать с разными протоколами, чтобы в случае проблем переключиться на другой.

Немного примеров из жизни, где были проблемы, связанные с реализацией:

  • Получаем netconf, а в ответе просто невалидный xml — забыли кавычки. Пришлось регуляркой править перед парсингом.

  • В gNMI мы подписываемся на метрики и должны получать сообщение об удалении метрики, например после удаления интерфейса. Но в этом случае устройство просто перестаёт присылать по нему оповещения. Приходится на своей стороне догадываться, что отсутствие данных через какое‑то время подразумевает удаление.

  • CLI должна быть нерушимым оплотом, базой, скрепами — но даже там очень легко ошибиться. Был случай, когда один вендор возвращал значения в виде таблицы:

iface  rx   tx  speed
iface1 123  456 100
iface2 12345123 100

Видимо, не рассчитали максимальную длину числа и одно наехало на другое. Такое даже можно как‑то распарсить, но затёртые младшие разряды уже не вернуть.

Ещё на выбор способа влияет интервал обновления данных. Часто потребителю хочется видеть данные как можно раньше и как можно точнее, особенно в случае аварии, а для этого нужно собирать данные как можно чаще. 

Устройства же не получают метрики синхронно при запросе, а отдают из кеша, который обновляется по своим таймерам. Более того, эти таймеры различаются для разных метрик: скажем, счётчик пакетов на физических интерфейсах может обновляться раз в 5 секунд, а такой же счётчик на агрегатных интерфейсах — раз в 10 секунд. Казалось бы, берём 10 секунд и радуемся красивым графикам, но нет, в таком случае на графиках иногда будут пилы. 

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

Рассмотрим, что будет, если поиграть интервалами опроса. Ниже пример данных с разным интервалом опроса (4, 15, 16, 29, 30 с). Интервал обновления данных 4 секунды.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 4

Из графика видно, что при кратности интервалов (4 и 16 секунд) график в целом выглядит очень близко к эталонному, но иногда бывают всплески. При несовпадении интервалов график всегда идёт либо выше, либо ниже эталонного. Например, для интервала получения 15 хорошо видно, что он получает один раз 800 (20% ошибка, так как остаток от деления 15 на 4 = 3, а это 20% от 15) и два раза по 1067. Среднее значение у всех графиков равно 1000.

Вот и получается, что интервал опроса точно должен быть больше интервала обновления счетчика и желательно кратно больше для более гладких графиков.

Что делать с метриками после получения

Очень часто полученные данные нужно обработать, так как в конечном счёте мы хотим сделать удобно потребителю, а не просто переложить чиселки с устройства в БД.

Пример из жизни: один вендор отдаёт уровень сигнала трансивера в ваттах, другой — в дБмВт. Если не привести к одному виду, то работа с такими метриками превращается из ремесла в искусство. Придётся создавать дашборды с указанием вендора или делать разные имена сенсоров rx_power_dbm, rx_power_mw и вместо одной проверки на все трансиверы вида alarm_if(rx_power < -16) — делать несколько проверок условий с разными значениями.

Если работать с gNMI, то фильтрация при подписке на данные очень ограничена (в отличие от SNMP) и мы получаем много лишних данных. Часть нужно отбросить, часть переименовать, а иногда и подмешать данные из внешних источников. В случае netconf в ответе получаем xml‑документ из которого нужно достать нужные поля. В редких случаях можно описать через xpath, что нужно достать, но чаще это полноценная функция с циклами и условиями (вендоры любят менять имена полей от версии к версии).

Почему мы решили использовать очередь сообщений

Мы давно пришли к модели: коллектор → очередь → потребители. Очередь сообщений — это удобный интерфейс для нас, он решает множество проблем по сравнению с обменом через TSDB или прямым взаимодействием клиентов и коллектора.

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

Но есть и минусы. Нужен дополнительный сервис для доставки данных в базу из очереди, а это дополнительное звено отказа. Конфигурация метрик размазана по двум сервисам: в коллекторе написано, как собирать, а в другом сервисе — как доставлять до базы.

Начинаем подготовку к написанию

Перед тем как садиться писать новый коллектор, мы собрали воедино все требования к нему.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 5

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

Процесс работы должен быть простым. В нашем старом коллекторе добавлением новых метрик занимались разработчики: инженеры формулировали требования, а реализацию брала на себя команда разработки. Со временем стало понятно, что инженеры хотят самостоятельно добавлять сбор метрик. Это потребовало снижения порога входа. Нужно, чтобы коллектор можно было запустить локально в удобной среде и протестировать конфигурацию без сложной инфраструктуры.

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

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

На уровне эксплуатации сервис должен поддерживать динамическую трассировку. Например, инженеры видят на графике что‑то странное. У них высвечиваются аномально большие значения, какие‑то петабиты в секунду. Тут должна быть возможность включить дебаг в продакшене и видеть детальную картину непосредственно в нём. По сырым данным проще понять на каком шаге проблема — на входе или дальше.

Требуются внутренние метрики состояния. Поскольку обработка многостадийная, важно видеть статус каждого шага.

Быстрый time‑to‑market для новых конфигураций — ещё одно обязательное требование. В старом коллекторе обновление конфигурации требовало рестарта сервиса, что приводило к разрывам на графиках. Новая система должна применять изменения без перезапуска, чтобы избежать потери данных и разрывов на графиках.

Почему свой, а не готовый

Прежде чем думать над своим коллектором, мы конечно же проверили существующие опенсорсные варианты. Самыми близкими к нашим требованиям оказались telegraf и vector.

Оба работают по примерно одинаковой схеме в виде пайплайна: «получение → обработка → вывод результата». Каждый такой шаг представляет из себя плагин и может быть добавлен несколько раз.

Например «плагин:snmp → плагин:подсчет скорости → плагин:запись в БД». В telegraf пайплайн неявный, то есть в конфигурации указан просто список плагинов и нет возможности указать, какой шаг с каким связан. Также нельзя указать, скажем, что «плагин:подсчёт скорости» должен применяться только для «плагин:snmp», он будет применяться ко всем данным. Единственное, что частично решает эту проблему, так это фильтрация в плагине — можно указать по каким параметрам применять плагин.

В vector в параметрах плагина можно указать, из какого плагина брать данные, и таким образом пайплайн выстраивается в направленный ациклический граф. С такими возможностями легко строить комплексную обработку данных.

Telegraf написан на Go и имеет огромный выбор плагинов. Это очень хорошо, когда вы хотите использовать его для сбора метрик со своего сервера. В то же время telegraf не предполагает использование в качестве библиотеки (а мы уверены, что придётся так или иначе делать правки для себя). Кроме того, в нём огромный список зависимостей с разнообразными лицензиями — огромная боль для монорепозитория. 

Vector в этом смысле полная противоположность telegraf. Очень мало плагинов, особенно связанных со сбором метрик с сетевых устройств, но разрабатывается он с расчётом на то, что может быть использован как библиотека.

Оба проекта не имеют поддержки отказоустойчивости, распределения нагрузки и динамических списков устройств (хотя в vector возможно через API менять конфигурацию). Следовательно, как есть проекты использовать не получится, нужно для них делать дополнительный сервис в котором будет провязка с нашими системами и реализация отказоустойчивости.

Godograf — наш новый коллектор метрик

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

Центральной частью является пайплайн, представляющий собой ациклический граф из плагинов трёх типов. 

  • Input‑плагины получают данные и отвечают за сбор метрик из внешних источников.

  • Transform‑плагины работают с внутренним форматом метрик. Они принимают метрики, выполняют обработку и передают их либо следующему transform‑плагину, либо в output.

  • Output‑плагины отправляют данные в очередь сообщений, на экран или в другие системы. 

Собираем 1 000 000 метрик в секунду с сетевых устройств - 6

Плагины соединяются в граф, что позволяет объединять несколько потоков данных в один кубик, или дублировать на разные кубики. Такая модель даёт возможность строить сложные схемы обработки и маршрутизации данных.

Помимо самого пайплайна есть и модули управления.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 7

Один из них — плагин типа Resolver. В конфигурации пайплайна не указываются конкретные хосты, поскольку они могут динамически меняться. Список устройств берётся из системы Inventory по заданным тегам. Например, можно указать тег конкретного вендора, и Resolver получит список соответствующих хостов из Inventory, запустит для каждого из них пайплайн и будет постоянно обновлять этот список.

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

Для управления системой и передачи внутренних метрик наружу реализован HTTP‑интерфейс. Для масштабируемости и отказоустойчивости предусмотрен отдельный кластерный плагин. В моём примере он работает через ZooKeeper, однако конкретная технология не принципиальна — это же плагины, их можно менять.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 8

Модуль кластера нужен чтобы распределять хосты, которые мы выгрузили, между запущенными экземплярами Godograf. Каждый экземпляр знает общее количество нод в кластере и свой порядковый номер. На основании этого он выбирает подмножество хостов, которые должен обслуживать. Логика выбора может учитывать любые параметры, например распределение по дата‑центрам или ещё как‑то.

В общем и целом, в модуле кластера сосредоточена логика принятия решения о том, какие устройства опрашивать конкретному экземпляру. После выбора соответствующий список хостов передаётся в Resolver, который запускает пайплайны для этих устройств.

Ниже примеры плагинов, которые можно использовать для сбора метрик.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 9

Python, коллектор и фишечки

Одной из особенностей коллектора стало применение Starlark для реализации кастомной логики. Инженеры Яндекса хорошо знают Python, однако запуск полноценного Python внутри сервиса на Go неудобен и небезопасен. 

Поэтому мы открылил для себя Starlark — встраиваемый язык, синтаксически близкий к Python. Он интерпретируемый, его можно встраивать непосредственно в конфигурацию и не нужно компилировать. Это позволяет быстро внедрять новые функции без рестарта сервиса. Заметным недостатком Starlark является сравнительно невысокая производительность, но с этим можно жить.

Вот пример кода Input‑плагина. На вид похоже на Python. В нём мы ходим по HTTP API в какую‑то систему, забираем метрики, конвертируем их во внутренний формат и на этом работа этого input‑плагина выполнена. Дополнительные преобразования выполняются уже на следующих этапах пайплайна. Задача input‑плагина — просто собрать метрики.

load("http.star", "http")

def do(target):
  req = http.Request("GET", url + target)
  resp = client.do(req)
  data = resp.json()
  result = parse_data(data, ts)
  return result

Существует интересная проблема. Если писать универсальный коллектор, условно, SNMP Network, в большинстве случаев он будет работать корректно. Там используются стандартные OID, проблем нет. Однако если появляется устройство, которое отвечает медленно или сильно нагружено, стандартные параметры опроса не подходят. Можно поменять значение в основном конфиге, но тогда другие будут медленно собираться, а вы этого вряд ли хотите. Можно сделать дубликат конфига, исключить из одного конфига медленные устройства и включить их во второй. Но получится копипаста, и нужно что‑то придумать, чтобы хосты не пересекались. Это крайне неудобно.

Поэтому мы сделали поддержку Starlark и в конфигах. В следующем примере нижняя часть — это код на Starlark. Он может быть встроен в YAML и вычисляет конфигурацию отдельно для каждого хоста. Starlark имеет доступ к параметрам конфигурации и может динамически изменять их для конкретного устройства. В примере мы поменяли интервалы опросов и размер запрашиваемого количества OID.

SNMP network:
 filters:
  - "rt%[all hosts]”
 inputs:
  snmp:
  type: snmp
  max_oids: 50
  finetuning: >
   def do(conf, target):
    tags = target.get_tags()
    # Huawei 2300 складываются по CPU от частых запросов
    if "Huawei 2300" in tags:
     conf.max_oids = 30
     conf.fields.interval = "60s"
     conf.indexes.interval = "900s"
   return conf

gNMI, переиспользование конфигураций и динамический дебаг

Просто интересно: напишите в комментариях, кто ещё опрашивает данные через gNMI и как это реализовали? Дело в том, что gNMI — это недавно появившийся протокол поверх gRPC, поддержку которого вендоры постепенно добавляют в свои устройства. Его фишка в том, что протокол работает в потоковом режиме: можно настроить подписку и получать только изменения значений, а не опрашивать устройство постоянно и получать одни и те же данные. Это позволяет уменьшить избыточный трафик и снизить задержку между изменением состояния и его получением.

Снаружи всё выглядит удобно, этакая красивая обёртка конфетки. Однако вкус этой конфетки зависит от конкретного вендора. Несмотря на наличие стандарта, детали поведения и набор доступных атрибутов могут различаться. Стандарт классный, всё предусмотрено, но вендор имеет своё видение.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 10

В нашем случае gNMI используется для сбора метрик интерфейсов. Интерфейсы отдают метрики каждую секунду. Можно рисовать очень красивые графики с минимальной задержкой. При этом возникает ограничение: в потоке gNMI нет параметра ifalias, который есть в SNMP.

Эта проблема решается на уровне пайплайна. В одном пайплайне мы указываем, что нужно собирать одновременно и SNMP, и gNMI. Далее используется transform‑плагин, который объединяет данные из двух источников. В нашем примере это тоже делается с помощью Starlark. Мы получаем сначала данные по SNMP, затем — по gNMI. Когда приходят метрики из gNMI, мы их насыщаем данными, которые получили из SNMP. И эти данные уже идут по пайплайну дальше.

Ещё мы можем делать разные хитрые схемы.

Собираем 1 000 000 метрик в секунду с сетевых устройств - 11

Предположим, у нас есть туннель между двумя хостами, и мы хотим посмотреть, теряются ли пакеты в этом туннеле. Для этого можно сравнить количество отправленных пакетов на одном конце и принятых на другом. 

Мы запускаем пайплайн на каждый хост отдельно: каждый пайплайн видит только данные своего хоста. Но чтобы понять, сколько пакетов реально потеряно между хостами, нужно объединить данные с обоих хостов. Для этого создаётся ещё один пайплайн, который получает на вход результаты работы двух других пайплайнов. Уже в этом объединённом пайплайне можно посчитать реальные потери пакетов.

У нас есть очень крутая функция «динамический дебаг». Нам она была нужна, и мы её сделали. 

Было бы здорово включить дебаг и видеть всё в логах, чтобы сразу понять, где проблема. Увы, это невозможно: у нас огромный объём данных — миллион метрик в секунду собирается. Дебагов наберётся на гигабит в секунду. Никто столько логов не выдержит. 

Поэтому мы сделали так: можно указать конкретный хост и пайплайн и только для них включается дебаг. Когда кто‑то сообщает о проблеме с хостом, мы включаем дебаг для этого хоста и пайплайна, смотрим логи и видим проблему уже во входных данных. После этого понятно, что нужно идти к вендору и решать проблему.

Этот механизм работает для каждого плагина, все плагины могут добавлять нужные данные в логи. Поскольку дебаг делается для одного хоста, можно выводить много информации — это не создаёт нагрузку на всю систему.

Итоги запуска коллектора и полезные советы

Собираем 1 000 000 метрик в секунду с сетевых устройств - 12

Что у нас получилось в итоге? Мы перенесли всю нагрузку на новый коллектор, кстати в процессе её стало даже больше — примерно в два раза по сравнению с предыдущим. Сейчас мы обрабатываем более миллиона метрик в секунду от 25 тысяч устройств. Это не только сетевое оборудование, но и множество других систем вроде PDU, DWDM. Всё это потребляет суммарно 40 ядер. 

Мы активно используем SNMP — получаем 16 тысяч SNMP‑пакетов в секунду, и выполняем около 400 команд в секунду, чтобы собирать данные из CLI.

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

  1. У вендоров есть своё видение протоколов и взаимодействия устройств. Поэтому важно делать своё решение гибким, ведь данные в любой момент могут повести себя странно, и нужно уметь быстро адаптироваться.

  2. Учтите: сетевые инженеры готовы участвовать в разработке новых конфигураций и плагинов. Сделайте им удобно, и они будут приходить с коммитами, а не только с задачами.

  3. Делайте динамический дебаг. У Vector и Telegraf это почему‑то не реализовано, а фича очень полезная.

  4. Делайте модули на максималках — проще разрабатывать, тестировать и подключать к работе нейросети, когда модули независимы.

  5. Делайте применение конфигов без рестарта — это дорогая, но крайне полезная фича, когда вы делаете отладку или выкатываете что‑то в прод. Просто пришли, поправили конфиг, сохранили всё, и изменения применились без каких‑либо потерь данных.

  6. Сделайте так, чтобы новую конфигурацию нельзя было добавлять без документации. Например, проверяйте это через CI. Используйте шаблоны, чтобы человек просто запускал makefile и получал готовый каркас документации, который остаётся только подправить.

Спасибо за внимание — и жду ваших вопросов в комментариях или в нашем сообществе Yandex Infrastructure, где мы рассказываем, как делаем инфраструктуру Яндекса.

Автор: gescheit

Источник

Rambler's Top100