Сегодня помимо монолитного кода наш проект включает в себя десятки микросервисов.
За каждым из них необходимо следить.
Сделать это в таких масштабах силами DevOps-инженеров проблематично.
Мы разработали систему мониторинга, которая работает как сервис для разработчиков.
Они могут самостоятельно записывать метрики в систему мониторинга, использовать их, строить на их основе дашборды и прикреплять к ним оповещения, которые будут срабатывать при достижении пороговых значений.
Для DevOps-инженеров — только инфраструктура и документация.
Этот пост представляет собой стенограмму моего выступления с нашим разделы в РИТ++.
Многие просили нас сделать оттуда текстовые версии отчетов.
Если вы были на конференции или смотрели видео, ничего нового вы не найдете.
А всем остальным - добро пожаловать под кат. Расскажу, как мы пришли к такой системе, как она работает и как мы планируем ее обновлять.
Прошлое: схемы и планы
Как мы пришли к нынешней системе мониторинга? Для того, чтобы ответить на этот вопрос, нужно перенестись в 2015 год. Вот как это выглядело тогда:У нас было около 24 нод, которые отвечали за мониторинг.
Там целая пачка разных крон, скриптов, демонов, которые так или иначе что-то мониторят, отправляют сообщения, выполняют функции.
Мы думали, что чем дальше мы зайдём, тем менее жизнеспособной будет такая система.
Разрабатывать его нет смысла: слишком громоздко.
Мы решили выбрать те элементы мониторинга, которые будем сохранять и развивать, и те, от которых откажемся.
Их было 19. Остались только графиты, агрегаторы и Графана в качестве дашборда.
Но как будет выглядеть новая система? Так:
У нас есть хранилище метрик: это графиты, которые будут базироваться на быстрых SSD-накопителях, это некие агрегаторы метрик.
Дальше — Графана для отображения дашбордов и Мойра для оповещений.
Еще мы хотели разработать систему поиска аномалий.
Стандарт: Мониторинг 2.0
Вот как выглядели планы в 2015 году.Но нам предстояло подготовить не только инфраструктуру и сам сервис, но и документацию к нему.
Мы разработали для себя корпоративный стандарт, который называем мониторинг 2.0. Какие требования были к системе?
- постоянная доступность;
- интервал хранения метрик = 10 секунд;
- структурированное хранилище метрик и дашбордов;
- Соглашение об уровне обслуживания > 99,99 %
- сбор метрик событий через UDP (!).
Если записать их все сразу в графит, хранилище рухнет. Мы также выбрали префиксы первого уровня для всех метрик.
Каждый из префиксов имеет какое-то свойство.
Существуют метрики для серверов, сетей, контейнеров, ресурсов, приложений и так далее.
Реализована четкая, строгая, типизированная фильтрация, при которой мы принимаем метрики первого уровня и просто отбрасываем остальные.
Вот как мы планировали эту систему в 2015 году.
Что сейчас?
Присутствует: схема взаимодействия компонентов мониторинга.
В первую очередь мы мониторим приложения: наш PHP-код, приложения и микросервисы — словом, все, что пишут наши разработчики.
Все приложения отправляют метрики по UDP в агрегатор Брубека (statsd, переписанный на C).
Он оказался самым быстрым в синтетических тестах.
И он отправляет уже агрегированные метрики в Graphite через TCP. У него есть тип метрик, называемый таймерами.
Это очень удобная вещь.
Например, для каждого подключения пользователя к сервису вы отправляете в Брубек метрику со временем ответа.
Пришёл миллион ответов, но агрегатор выдал всего 10 метрик.
У вас есть количество пришедших людей, максимальное, минимальное и среднее время ответа, медиана и 4 процентиля.
Потом данные передаются в Graphite и мы видим все это вживую.
У нас также есть агрегирование метрик по оборудованию, программному обеспечению, системным метрикам и нашей старой системе мониторинга Munin (она работала у нас до 2015 года).
Собираем все это через C-демона CollectD (в него встроена целая куча разных плагинов, он может опрашивать все ресурсы хост-системы, на которой он установлен, просто укажите в конфигурации, куда записывать данные) и через него запишите данные в Graphite. Он также поддерживает плагины Python и сценарии оболочки, поэтому вы можете писать свои собственные решения: CollectD соберет эти данные с локального или удаленного хоста (при условии, что Curl) и отправит их в Graphite. Затем мы отправляем все собранные метрики в Carbon-c-relay. Это решение Carbon Relay от Graphite, модифицированное на C. Это маршрутизатор, который собирает все метрики, которые мы отправляем от наших агрегаторов, и маршрутизирует их на узлы.
Также на этапе маршрутизации проверяется валидность метрик.
Во-первых, они должны соответствовать той схеме приставки, которую я показал ранее и, во-вторых, справедливы для графита.
В противном случае они упадут. Затем Carbon-c-relay отправляет метрики в кластер Graphite. В качестве основного хранилища метрик мы используем Carbon-cache, переписанный на Go. Go-carbon благодаря своей многопоточности значительно превосходит Carbon-cache по производительности.
Он получает данные и записывает их на диски с помощью пакета шепота (стандартного, написанного на питоне).
Для чтения данных из наших хранилищ мы используем Graphite API. Это намного быстрее, чем стандартный Graphite WEB. Что происходит с данными дальше? Они идут в Графану.
В качестве основного источника данных мы используем наши графитовые кластеры, плюс у нас есть Grafana в качестве веб-интерфейса для отображения метрик и построения дашбордов.
Для каждого своего сервиса разработчики создают собственную панель управления.
Потом на их основе строят графики, на которых отображаются метрики, которые они пишут из своих приложений.
Помимо Grafana, у нас есть еще SLAM. Это демон Python, который рассчитывает SLA на основе данных из графита.
Как я уже говорил, у нас есть несколько десятков микросервисов, у каждого из которых свои требования.
С помощью SLAM мы заходим в документацию и сравниваем ее с тем, что есть в Graphite и сравниваем, насколько требования соответствуют доступности наших сервисов.
Пойдем дальше: оповещение.
Он организован с использованием сильной системы — Мойры.
Он независим, потому что под капотом у него собственный Графит. Разработан ребятами из СКБ "Контур", написан на Python и Go, полностью с открытым исходным кодом.
Мойра получает тот же поток, что и графиты.
Если по какой-то причине ваше хранилище выйдет из строя, ваши оповещения все равно будут работать.
Мы развернули Moira в Kubernetes; в качестве основной базы данных он использует кластер серверов Redis. В результате получилась отказоустойчивая система.
Он сравнивает поток метрик со списком триггеров: если в нем нет упоминаний, то отбрасывает метрику.
Таким образом, он способен переваривать гигабайты метрик в минуту.
К нему мы также подключили корпоративный LDAP, с помощью которого каждый пользователь корпоративной системы может создавать для себя уведомления на основе существующих (или вновь создаваемых) триггеров.
Поскольку Moira содержит Graphite, она поддерживает все его функции.
Итак, вы сначала берете строку и копируете ее в Grafana. Посмотрите, как данные отображаются на графиках.
А потом вы берете ту же строку и копируете ее в Мойру.
Вешаешь лимиты и получаешь оповещение на выходе.
Чтобы сделать все это, вам не нужны какие-то специфические знания.
Мойра может оповещать через SMS, электронную почту, Jira, Slack. Она также поддерживает выполнение пользовательских сценариев.
Когда с ней случается триггер и она подписана на пользовательский скрипт или бинарный файл, она запускает его и отправляет JSON на стандартный ввод для этого бинарника.
Соответственно, ваша программа должна его разобрать.
Что вы будете делать с этим JSON, зависит от вас.
Хотите — отправляйте в Telegram, хотите — открывайте задачи в Jira, делайте что угодно.
Также для оповещения мы используем собственную разработку — Имаготаг.
Мы адаптировали панель, которую обычно используют для электронных ценников в магазинах, под свои нужды.
Мы привезли в него триггеры от Мойры.
Он указывает, в каком состоянии они находятся и когда они произошли.
Некоторые разработчики отказались от уведомлений в Slack и электронной почты в пользу этой панели.
Ну а так как мы прогрессивная компания, мы мониторили и Kubernetes в этой системе.
Мы включили его в систему с помощью Heapster, который установили в кластер, он собирает данные и отправляет их в Graphite. В результате диаграмма выглядит так:
Компоненты мониторинга
Вот список ссылок на компоненты, которые мы использовали для этой задачи.
Все они имеют открытый исходный код.
Графит:
- идти-карбон: github.com/lomik/go-carbon
- шепот: github.com/graphite-project/whisper
- графит-API: github.com/brutasse/graphite-api
Карбоновое реле:
github.com/grobian/carbon-c-relayБрубек:
github.com/github/brubeckСобрано:
Collectd.orgМойра:
github.com/moira-alertГрафана:
Grafana.comХипстер:
github.com/kubernetes/heapsterСтатистика
И вот несколько цифр о том, как система работает у нас.
Агрегатор (Брубек)
Количество метрик: ~300 000/сек.Интервал отправки метрик в Graphite: 30 сек.
Использование ресурсов сервера: ~6% CPU (речь идет о полноценных серверах); ~ 1Гб оперативной памяти; ~3 Мбит/с локальная сеть
Графит (карбон)
Количество метрик: ~ 1 600 000/мин Интервал обновления метрик: 30 секунд. Схема хранения метрик: 30сек 35д, 5мин 90д, 10мин 365д (даёт понимание того, что происходит с сервисом за длительный период времени) Использование ресурсов сервера: ~10% ЦП; ~ 20Гб оперативной памяти; ~30 Мбит/с локальная сетьГибкость
Мы в Авито очень ценим гибкость в нашей службе мониторинга.Почему он на самом деле оказался таким? Во-первых, его компоненты взаимозаменяемы: как сами компоненты, так и их версии.
Во-вторых, поддерживаемость.
Поскольку весь проект с открытым исходным кодом, вы можете самостоятельно редактировать код, вносить изменения и реализовывать функции, недоступные из коробки.
Используются довольно распространенные стеки, в основном Go и Python, поэтому делается это достаточно просто.
Вот пример реальной проблемы.
Метрика в Graphite — это файл.
У него есть имя.
Имя файла = имя метрики.
И есть способ туда добраться.
Имена файлов в Linux ограничены 255 символами.
И у нас есть (в качестве «внутренних заказчиков») ребята из отдела баз данных.
Они говорят нам: «Мы хотим отслеживать наши SQL-запросы.
И они не по 255 символов, а по 8 МБ каждый.
Мы хотим отобразить их в Grafana, увидеть параметры этого запроса, а еще лучше — увидеть топ таких запросов.
Будет здорово, если это будет отображаться в реальном времени.
Было бы здорово поставить их в боевую готовность».
Пример SQL-запроса взят в качестве примера из сайт postgrespro.ru
Настраиваем Redis-сервер и используем наши плагины Collectd, которые заходят в Postgres и берут оттуда все данные, отправляя метрики в Graphite. Но мы заменяем имя метрики хэшами.
Мы одновременно отправляем в Redis один и тот же хеш в качестве ключа, а в качестве значения — весь SQL-запрос.
Все, что нам нужно сделать, это убедиться, что Grafana может обратиться к Redis и получить эту информацию.
Мы открываем Graphite API, потому что.
это основной интерфейс взаимодействия всех компонентов мониторинга с графитом, и мы вводим туда новую функцию под названием aliasByHash() — из Grafana получаем имя метрики, и используем ее.
в запросе к Redis в качестве ключа, в ответ мы получаем значение ключа, который является нашим «SQL-запросом»».
Таким образом, мы отобразили в Grafana отображение SQL-запроса, который теоретически невозможно было там отобразить, а также со статистикой по нему (вызовы, строки, общее_время,.
).
Полученные результаты
Доступность.Наш сервис мониторинга доступен 24/7 из любого приложения и любого кода.
Если у вас есть доступ к хранилищам, вы можете записывать данные в сервис.
Язык не важен, решения не важны.
Вам нужно только знать, как открыть сокет, поставить туда метрику и закрыть сокет. Надежность.
Все компоненты отказоустойчивы и хорошо справляются с нашими нагрузками.
Низкий барьер входа.
Для того, чтобы использовать эту систему, вам не нужно изучать языки программирования и запросы в Grafana. Просто откройте свое приложение, введите в него сокет, который будет отправлять метрики в Graphite, закройте его, откройте Grafana, создайте там дашборды и посмотрите на поведение ваших метрик, получая уведомления через Мойру.
Независимость.
Все это вы можете сделать самостоятельно, без помощи DevOps-инженеров.
И это преимущество, ведь вы можете следить за своим проектом прямо сейчас, вам не придется никого просить – ни о начале работы, ни о внесении изменений.
К чему мы стремимся?
Все перечисленное ниже – это не просто абстрактные мысли, а нечто, к чему сделаны хотя бы первые шаги.
- Детектор аномалий.
Мы хотим создать сервис, который будет обращаться к нашим хранилищам Graphite и проверять каждую метрику с помощью различных алгоритмов.
Уже есть алгоритмы, которые мы хотим просмотреть, есть данные, мы знаем, как с ними работать.
- Метаданные.
Сервисов у нас много, они со временем меняются, как и люди, которые с ними работают. Постоянное ведение документации вручную — не вариант. Вот почему сейчас мы встраиваем метаданные в наши микросервисы.
Там указано, кто его разработал, языки, с которыми он взаимодействует, требования SLA, куда и кому следует отправлять уведомления.
При развертывании службы все данные объекта создаются независимо.
В результате вы получаете две ссылки — одну на триггеры, другую на дашборды в Grafana.
- Мониторинг в каждом доме.
Мы считаем, что все разработчики должны использовать такую систему.
В этом случае вы всегда понимаете, где находится ваш трафик, что с ним происходит, куда он падает, где его слабые места.
Если, например, что-то придет и у вас выйдет из строя сервис, то вы узнаете об этом не во время звонка менеджера, а из оповещения, и сможете сразу открыть последние логи и посмотреть, что там произошло.
- Высокая производительность.
Наш проект постоянно растет и сегодня обрабатывает около 2 000 000 значений метрики в минуту.
Год назад эта цифра составляла 500 тысяч.
И рост продолжается, а это значит, что через какое-то время Графит (шепот) начнет сильно нагружать дисковую подсистему.
Как я уже говорил, данная система мониторинга достаточно универсальна благодаря взаимозаменяемости компонентов.
Кто-то поддерживает и постоянно расширяет свою инфраструктуру специально для Graphite, но мы решили пойти другим путём: использовать Кликхаус в качестве хранилища наших метрик.
Этот переход практически завершен, и совсем скоро я расскажу подробнее, как это делалось: какие были трудности и как их преодолевали, как проходил процесс миграции, опишу выбранные в качестве привязки компоненты и их конфигурации.
Возможно, у кого-то есть опыт построения подобной системы мониторинга или перехода на Clickhouse в подобной ситуации — поделитесь в комментариях.
Теги: #Хранение данных #Системное администрирование #DevOps #Микросервисы #мониторинг #clickhouse #Grafana #avito #graphite #heapster #collectd #moira #carbon-c-relay #brubeck
-
Reactjs + Mobx — Опыт Использования Di
19 Oct, 24