Семейство Open Source Metrics приветствует Catalyst и Erlenmeyer

В OVHcloud Metrics мы любим открытый исходный код! Наша цель — предоставить всем нашим пользователям полноценный опыт . Мы полагаемся на базу данных временных рядов Warp10, которая позволяет нам создавать инструменты с открытым исходным кодом для наших пользователей. Давайте взглянем на некоторые из них в этом блоге.



Инструмент для хранения

Наша инфраструктура основана на базе данных временных рядов с открытым исходным кодом: Warp10 . Эта база данных включает две версии: автономную и распределенную . Распределенный полагается на распределенные инструменты, такие как Apache Kafka, Apache Hadoop и Apache HBase .

Неудивительно, что наша команда вносит свой вклад в платформу Warp10 . Из-за наших уникальных требований мы даже вносим свой вклад в базовую базу данных с открытым исходным кодом HBase !

Прием данных метрик

Собственно говоря, мы были первыми, кто застрял в процессе приема ! Мы часто создаем адаптированные инструменты для сбора и отправки данных мониторинга на Warp10 — так появился noderig . Noderig является адаптированным инструментом , который способен собрать в простое ядро метрик с любого сервера или любой виртуальной машины . Также можно безопасно отправлять метрики на бэкэнд. Beamium , инструмент Rust, может передавать метрики Noderig одному или нескольким бэкэндам Warp 10 .



Что, если я хочу собирать собственные специальные показатели ? Во-первых, вам нужно будет разоблачить их по «модели Прометея». Beamium затем может подручных приложений на основе их файл конфигурации и вперед все данные в сконфигурированной Деформация 10 бэкэндом (ов)!

Если вы хотите отслеживать определенные приложения с помощью агента Influx Telegraf (чтобы предоставить необходимые вам метрики), мы также предоставили соединитель Warp10 Telegraf , который был недавно объединен!

Пока это выглядит великолепно, но что, если я обычно нажимаю метрики Graphite, Prometheus, Influx или OpenTSDB ; как я могу просто перейти на Warp10 ? Наш ответ - Catalyst : прокси-уровень, который может анализировать метрики в связанных форматах и ​​преобразовывать их в родной для Warp10.

Катализатор

Catalyst  — это HTTP-прокси Go, используемый для анализа нескольких записей в базе данных TimeSeries с открытым исходным кодом. На данный момент он поддерживает несколько операций записи в базу данных TimeSeries с открытым исходным кодом; такие как OpenTSDB, PromQL, Prometheus-remote_write, Influx и Graphite. Catalyst запускает HTTP-сервер, который прослушивает определенный путь ; начиная с имени временного ряда протокола, а затем с собственного запроса . Например, чтобы собрать данные о притоке, вы просто отправляете запрос на адрес 
influxdb/write
. Catalyst автоматически проанализирует 
influx
данные и преобразует их в собственный формат приема Warp 10 .



Запросы метрик

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

Теперь давайте возьмем пользователя, который использует Telegraf и отправляет данные в Warp10 с помощью Catalyst. Они захотят использовать встроенную панель управления Influx Grafana, но как? А как насчет пользователей, которые автоматизируют запросы с помощью протокола запросов OpenTSDB? Нашим ответом было разработать прокси: Эрленмейер

Эрленмейер

Erlenmeyer  — это HTTP-прокси Go, который позволяет пользователям запрашивать Warp 10 на основепротокола запросовс открытым исходным кодом . На данный момент он поддерживает несколько форматов TimeSeries с открытым исходным кодом; такие как PromQL, удаленное чтение Prometheus, InfluxQL, OpenTSDB или Graphite. Эрленмейер запускает HTTP-сервер, который прослушивает определенный путь ; начиная с имени временного ряда протокола, а затем с собственного запроса . Например, чтобы выполнить запрос promQL, пользователь отправляет запрос в
prometheus/api/v0/query
. Эрленмейер изначально проанализирует
promQL
запрос, а затем создаст собственный запрос WarpScript, который может поддерживатьлюбойбэкэнд Warp10 .



Продолжение следует

Сначала Erlenmeyer и Catalyst представили быструю реализацию собственных протоколов, призванную помочь внутренним группам выполнять миграцию, при этом используя знакомый инструмент . Теперь мы интегрировали множество встроенных функций каждого протокола и чувствуем, что они готовы к совместному использованию. Это время , чтобы сделать их доступными для Warp10 сообщества , поэтому мы можем получить обратную связь и продолжать работать в поддержке протоколов с открытым исходным кодом. Вы можете найти нас в игровой комнате OVHcloud Metrics !

Другим пользователям Warp10 может потребоваться нереализованный протокол. Они смогут использовать Erlenmeyer и Catalyst для поддержки их на собственном сервере Warp10.

Добро пожаловать, Erlenmeyer и Catalyst — Metrics Open Source проекты!

Jerem: Agile-бот

В OVHCloud мы открываем исходный код для нашего проекта «Agility Telemetry». Джерем , как наш сборщик данных, является основным компонентом этого проекта. Джерем регулярно очищает нашу JIRA и извлекает определенные показатели для каждого проекта. Затем он пересылает их в наше приложение для длительного хранения, платформу данных метрик OVHCloud .



Концепции Agility с точки зрения разработчика

Чтобы помочь вам понять наши цели для Jerem , нам нужно объяснить некоторые концепции Agility, которые мы будем использовать. Во-первых, мы составим техническую ежеквартальную дорожную карту для продукта, в которой изложены все функции, которые мы планируем выпускать каждые три месяца. Это то, что мы называем эпосом .

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

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

Однако во время спринтов могут неожиданно возникнуть другие срочные задачи. Это то, что мы называем препятствием . Например, нам может потребоваться помощь клиентам, исправление ошибок или срочные инфраструктурные задачи.   

Как работает Джерем

В OVH мы используем JIRA для отслеживания нашей активности. Наш Jerem бот обрывки наших проектов из JIRA и экспорта всех необходимых данных для нашей OVHCloud Метрики платформы данных . Джерем также может передавать данные в любую базу данных, совместимую с Warp 10. В Grafana вы просто запрашиваете платформу Metrics (используя источник данных Warp10 ), например, с помощью нашей панели управления программами . Все ваши KPI теперь доступны на красивой панели инструментов!



Откройте для себя показатели Jerem

Теперь, когда у нас есть обзор основных задействованных концепций Agility, давайте погрузимся в Джерема! Как преобразовать эти концепции гибкости в показатели? Прежде всего, мы извлечем все показатели, относящиеся к эпикам (т.е. новым функциям). Затем мы подробно рассмотрим метрики спринта.

Эпические данные

Чтобы объяснить эпические метрики Джерема, мы начнем с создания новой. В этом примере мы назвали это Agile Telemetry. Мы добавляем лейбл Q2-20, что означает, что мы планируем выпустить его во втором квартале. Чтобы записать эпопею с Джеремом, вам нужно установить четверть для окончательной доставки! Затем мы просто добавим четыре задачи, как показано ниже:



Чтобы получить метрики, нам нужно оценить каждую отдельную задачу. Мы сделаем это вместе на подготовительных сессиях. В этом примере у нас есть собственные очки истории для каждой задачи. Например, мы оценили write a BlogPost about Jeremзадачу на 3.



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

  • jerem.jira.epic.storypoint
    : общее количество очков истории, необходимых для завершения этой эпопеи. Значение здесь 14 (сумма всех очков эпической истории). Этот показатель будет развиваться каждый раз, когда эпик обновляется путем добавления или удаления задач. 
  • jerem.jira.epic.storypoint.done
    : количество выполненных задач. В нашем примере мы уже выполнили 
    Write Jerem bot
    и 
    Deploy Jerem Bot
    , поэтому мы уже выполнили восемь пунктов истории.
  • jerem.jira.epic.storypoint.inprogress
    : количество «выполняемых» задач, например 
    Write a BlogPost about Jerem
    .
  • jerem.jira.epic.unestimated
    : количество неоцененных задач, как 
    Unestimated Task
    в нашем примере.
  • jerem.jira.epic.dependency
    : количество задач, у которых есть метки зависимостей, указывающие, что они являются обязательными для других эпиков или проектов.



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

Данные спринта

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

Итак, давайте откроем новый спринт в JIRA и начнем работать над нашей задачей. Это дает нам следующее представление JIRA:



Джерем собирает следующие показатели для каждого спринта:

  • erem.jira.sprint.storypoint.total
    : общее количество очков истории, набранных в спринт.
  • jerem.jira.sprint.storypoint.inprogress
    : сюжетные точки, которые в настоящее время выполняются в рамках спринта.
  • jerem.jira.sprint.storypoint.done
    : количество очков истории, набранных на данный момент за спринт.
  • jerem.jira.sprint.events
    : даты начала и окончания спринта, записанные как строковые значения Warp10.



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

Данные о препятствиях

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

Мы можем добавить в JIRA специальные билеты, чтобы отслеживать выполнение этой задачи. Это то, что мы называем «препятствием». Они маркируются в соответствии с их природой. Если, например, постановка требует вашего внимания, то это препятствие «Инфра». Вы также получите метрики для «Всего» (все виды препятствий), «Избыточности» (незапланированные задачи), «Поддержка» (помощь товарищам по команде) и «Исправление ошибок или другое» (для всех других видов препятствий).

Каждое препятствие принадлежит активному спринту, в котором оно было закрыто. Чтобы закрыть препятствие, вам нужно только пометить его как «Готово» или «Закрыто».

Мы также получаем такие показатели, как:

  • jerem.jira.impediment.TYPE.count
    : количество препятствий, возникших во время спринта.
  • jerem.jira.impediment.TYPE.timespent
    : количество времени, затраченного на устранение препятствий во время спринта.

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



Чтобы начать запись препятствий, мы просто создаем новую задачу JIRA, в которую добавляем метку «препятствие». Мы также устанавливаем его характер и фактическое время, потраченное на это.



В качестве препятствия мы также извлекаем глобальные метрики, которые всегда записывает Джерем:

  • jerem.jira.impediment.total.created: время, затраченное с даты создания на устранение препятствия. Это позволяет нам получить общее количество препятствий. Мы также можем записывать все действия с препятствиями, даже вне спринтов.

Для одного проекта Jira, как в нашем примере, вы можете ожидать около 300 показателей. Это может увеличиваться в зависимости от эпика, который вы создаете и помечаете в Jira, и того, который вы закрываете.

Панель управления Grafana

Нам нравится создавать информационные панели Grafana! Они дают команде и менеджеру много информации о ключевых показателях эффективности. Лучшее в этом для меня, как разработчика, — это то, что я понимаю, почему хорошо выполнять задачу JIRA!

На нашей первой панели управления Grafana вы найдете все лучшие KPI для управления программами. Начнем с глобального обзора:

Обзор квартальных данных



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

Данные активного спринта



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

Подробные данные



В последней части представлены более подробные данные. Используя переменную epic Grafana, мы можем проверять конкретные эпики, а также завершение более глобальных проектов. У вас также есть velocity chart, который отображает прошлый спринт и сравнивает ожидаемые баллы истории с фактически завершенными.

Панель управления Grafana доступна напрямую в проекте Jerem. Вы можете импортировать его прямо в Grafana, если у вас настроен действительный источник данных Warp 10.

Чтобы панель управления работала должным образом, вам необходимо настроить переменную проекта Grafana в виде списка WarpScript [ 'SAN' 'OTHER-PROJECT' ]. Если наш программный менеджер может это сделать, я уверен, вы сможете!

Настройка Jerem и автоматическая загрузка данных управления программами дают нам много полезного. Мне как разработчику это очень нравится, и я быстро привык отслеживать в JIRA гораздо больше событий, чем раньше. Вы можете напрямую видеть влияние ваших задач. Например, вы видите, как быстро продвигается дорожная карта, и можете определить любые узкие места, которые создают препятствия. Затем эти узкие места становятся эпопеями. Другими словами, как только мы начинаем использовать Jerem, мы просто заполняем его автоматически! Надеюсь, вам тоже понравится! Если у вас есть отзывы, мы будем рады их услышать.

Вклад в Apache HBase: настраиваемая балансировка данных

В сегодняшнем блоге мы собираемся взглянуть на наш вклад в разработку стохастического балансировщика нагрузки Apache HBase, основанный на нашем опыте запуска кластеров HBase для поддержки мониторинга OVHcloud.



Контекст

Вы когда-нибудь задумывались, как:

  • мы генерируем графики для вашего сервера OVHcloud или пакета веб-хостинга?
  • наши внутренние команды контролируют свои собственные серверы и приложения?

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

Мы перепробовали множество различных баз данных временных рядов и в итоге выбрали Warp10 для обработки наших рабочих нагрузок. Warp10 может быть интегрирован с различными решениями для работы с большими данными, предоставляемыми Apache Foundation. В нашем случае мы используем Apache HBase в качестве хранилища данных долгосрочного хранения для наших показателей.

Apache HBase , хранилище данных, построенное на основе Apache Hadoop , предоставляет эластичную распределенную карту с упорядочением по ключам. Таким образом, одна из ключевых особенностей Apache HBase для нас — это возможность сканировать , то есть получать ряд ключей. Благодаря этой функции мы можем оптимизировать тысячи точек данных .

У нас есть собственные выделенные кластеры, самый большой из которых имеет более 270 узлов для распределения наших рабочих нагрузок:

  • от 1,6 до 2 миллионов операций записи в секунду, 24/7
  • от 4 до 6 миллионов чтений в секунду
  • около 300 ТБ телеметрии, хранящейся в Apache HBase

Как вы, вероятно, можете себе представить, хранение 300 ТБ данных на 270 узлах сопряжено с некоторыми проблемами, связанными с перераспределением, поскольку каждый бит является горячими данными и должен быть доступен в любое время. Давайте нырнем!

Как работает балансировка в Apache HBase?

Прежде чем погрузиться в балансировщик, давайте посмотрим, как он работает. В Apache HBase данные разделяются на сегменты, вызываемые Regionsи распределяемые по ним RegionServers. Количество регионов будет увеличиваться по мере поступления данных, и в результате регионы будут разделены. Вот тут-то и пригодится Balancer. Он будет перемещать регионы, чтобы избежать появления горячих точек, RegionServerи эффективно распределяет нагрузку.



Фактическая реализация, называемая StochasticBalancer, использует подход, основанный на затратах:

  1. Сначала он вычисляет общую стоимость кластера, проходя через цикл 
    cost functions
    . Каждая функция стоимости возвращает число от 0 до 1 включительно , где 0 — это решение с наименьшей стоимостью и лучшим решением, а 1 — с максимально возможной стоимостью и наихудшим решением. Apache Hbase поставляется с несколькими функциями стоимости, которые измеряют такие вещи, как загрузка региона, загрузка таблицы, локальность данных, количество регионов на сервер RegionServer… Вычисленные затраты масштабируются с помощью соответствующих коэффициентов, определенных в конфигурации .
  2. Теперь, когда начальная стоимость вычислена, мы можем попробовать 
    Mutate
    наш кластер. Для этого Balancer создает случайный случай 
    nextAction
    , который может быть чем-то вроде замены двух регионов или перемещения одного региона на другой RegionServer . Действие применяется виртуально , после чего рассчитывается новая стоимость . Если новая стоимость ниже нашей предыдущей, действие сохраняется. В противном случае он пропускается. Эта операция повторяется 
    thousands of times
    , поэтому файл 
    Stochastic
    .
  3. В конце список допустимых действий применяется к фактическому кластеру.

Что у нас не работало?

Мы выяснили это для нашего конкретного варианта использования , который включает:

  • Один стол
  • Выделенные Apache HBase и Apache Hadoop, адаптированные к нашим требованиям
  • Хорошее распределение ключей

… Количество регионов на RegionServer было для нас настоящим пределом

Даже если стратегия балансировки кажется простой, мы действительно считаем, что возможность запускать кластер Apache HBase на разнородном оборудовании жизненно важна , особенно в облачных средах, потому что вы, возможно, не сможете снова купить те же спецификации сервера в будущем. В нашем предыдущем примере наш кластер вырос с 80 до 250 машин за четыре года. За это время мы купили новые ссылки на выделенные серверы и даже протестировали некоторые специальные внутренние ссылки.

В итоге мы получили разные группы оборудования: некоторые серверы могут обрабатывать только 180 регионов, тогда как самые большие могут обрабатывать более 900 . Из-за этого несоответствия нам пришлось отключить балансировщик нагрузки, чтобы избежать использования RegionCountSkewCostFunction , которая попыталась бы перенести все RegionServers в одно и то же количество регионов.



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

Открытый исходный код лежит в основе OVHcloud , и это означает, что мы создаем наши инструменты на основе программного обеспечения с открытым исходным кодом, но также мы вносим свой вклад и возвращаем его сообществу. Когда мы поговорили, мы увидели, что не только нас беспокоит проблема гетерогенного кластера. Мы решили переписать наш инструментарий, чтобы сделать его более общим, и внести его непосредственно в проект HBase .

Наш вклад

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

Второй вклад касался добавления дополнительной функции costFunction для балансировки регионов в соответствии с правилом емкости.

Как это работает?

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

rs[0-9] 200
rs1[0-9] 50



RegionServers с именами хостов, соответствующими первым правилам, будут иметь ограничение 200 , а остальные 50 . Если совпадений нет, устанавливается значение по умолчанию.

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

Они 
HeterogeneousRegionCountCostFunction 
постараются сбалансировать регионы по своим возможностям.

Возьмем пример… Представьте, что у нас есть 20 RS:



  • 10 RS, названный 
    rs0
    в 
    rs9
    , нагруженные 60 регионов каждый, каждый из которых может рукоятку 200 регионов.
  • 10 RS, названные 
    rs10
    в 
    rs19
    , нагруженные 60 регионов каждый, каждый из которых может обрабатывать 50 областей.


Итак, исходя из следующих правил

rs[0-9] 200
rs1[0-9] 50


… Мы видим, что вторая группа перегружена, тогда как в первой группе много места.

Мы знаем, что можем обрабатывать максимум 2500 регионов (200 × 10 + 50 × 10), и в настоящее время у нас есть 1200 регионов (60 × 20). Таким образом, система 
HeterogeneousRegionCountCostFunction
поймет, что кластер заполнен на 48,0% (1200/2500). Основываясь на этой информации, мы попытаемся поставить все серверы RegionServers на ~ 48% нагрузки в соответствии с правилами.



Куда дальше?

Благодаря участникам Apache HBase наши исправления теперь объединены в основную ветку. Как только сопровождающие Apache HBase опубликуют новый выпуск, мы развернем и будем использовать его в любом масштабе. Это позволит больше автоматизировать с нашей стороны и упростит операции для группы наблюдения.

Участие было потрясающим путешествием. Что мне больше всего нравится в открытом исходном коде, так это возможность внести свой вклад и создать более надежное программное обеспечение. У нас было мнение о том, как следует решать ту или иную проблему, но обсуждения с сообществом помогли нам уточнить ее . Мы поговорили с инженерами из других компаний, которые, как и мы , испытывали трудности с развертыванием облака Apache HBase , и благодаря этим обменам наш вклад становился все более и более актуальным.

TSL (или как запрашивать базы данных временных рядов)

В прошлом году мы выпустили TSL как инструмент с открытым исходным кодом для выполнения запросов к Деформация 10 платформы, и выдвижением, OVHcloud Метрики Платформа данных .



Но как она развивалась с тех пор? Готов ли TSL запрашивать другие базы данных временных рядов ? Что насчет состояний TSL в экосистеме Warp10 ?

TSL для запроса многих баз данных временных рядов

Мы хотели, чтобы TSL можно было использовать перед несколькими базами данных временных рядов . Вот почему мы также выпустили генератор запросов PromQL .

Год спустя мы теперь знаем, что это был не лучший путь. Исходя из того, что мы узнали, тот TSL-адаптер проект был открытым исходным кодом, как доказательство концепции , как TSL может быть использован для запроса не-Деформация 10 базы данных. Проще говоря, TSL-адаптер позволяет TSL запрашивать InfluxDB .

Что такое TSL-адаптер?

TSL-адаптер — это API Quarkus JAVA REST, который можно использовать для запроса серверной части. TSL-адаптер анализирует запрос TSL, идентифицирует операцию выборки и загружает исходные необработанные данные из серверной части. Затем он вычисляет операции TSL с данными, прежде чем вернуть результат пользователю. Основная цель TSL-Adapter - сделать TSL доступным поверх других TSDB .



Говоря конкретно, мы запускаем JAVA REST API, который интегрирует библиотеку WarpScript в среду выполнения. Затем TSL используется для компиляции запроса в действительный запрос WarpScript. Это полностью прозрачно и касается только запросов TSL на стороне пользователя.


Чтобы загрузить необработанные данные из InfluxDB, мы создали расширение WarpScript. Это расширение объединяет абстрактный класс, 
LOADSOURCERAW
который необходимо реализовать для создания источника данных TSL-Adapter. Для этого требуется всего два метода: 
find
и 
fetch
Find
собирает все селекторы серий, соответствующие запросу (имена классов, теги или метки), при этом 
fetch
фактически извлекает необработанные данные за определенный промежуток времени.

Приток запросов с TSL-адаптером

Для начала просто запустите InfluxDB локально на порту 8086. Затем давайте запустим агент Telegraf притока и запишем данные Telegraf на локальном экземпляре притока.

Затем убедитесь, что вы локально установили TSL-адаптер и обновили его конфигурацию, указав путь к tsl.soбиблиотеке.

Чтобы указать собственный адрес притока или базы данных, обновите файл конфигурации TSL-адаптера соответствующим образом.

Вы можете запустить TSL-адаптер с помощью следующего примера команды:

java -XX:TieredStopAtLevel=1 -Xverify:none -Djava.util.logging.manager=org.jboss.logmanager.LogManager -jar build/tsl-adaptor-0.0.1-SNAPSHOT-runner.jar


И это все! Теперь вы можете запрашивать свою базу данных притока с помощью TSL и TSL-адаптера.

Начнем с восстановления временного ряда, относящегося к измерениям диска.

curl --request POST \
  --url http://u:p@0.0.0.0:8080/api/v0/tsl \
  --data 'select("disk")'


Теперь давайте воспользуемся возможностями аналитики TSL!

Во-первых, мы хотели бы получить только данные, содержащие установленный режим rw.

curl --request POST \
  --url http://u:p@0.0.0.0:8080/api/v0/tsl \
  --data 'select("disk").where("mode=rw")'


Мы хотели бы получать максимальное значение через каждые пятиминутные интервалы за последние 20 минут. Таким образом, запрос TSL будет:

curl --request POST \
  --url http://u:p@0.0.0.0:8080/api/v0/tsl \
  --data 'select("disk").where("mode=rw").last(20m).sampleBy(5m,max)'


Теперь ваша очередь повеселиться с TSL и InfluxDB. Вы можете найти подробную информацию обо всех реализованных функциях в документации TSL. Наслаждайтесь исследованием!

Что нового в TSL с Warp10?

Изначально мы создавали TSL как прокси GO перед Warp10. TSL теперь интегрировал экосистему Warp 10 как расширение Warp10 или как библиотеку WASM ! Мы также добавили несколько новых собственных функций TSL, чтобы сделать язык еще богаче!

TSL как функция WarpScript

Чтобы TSL работал как функция Warp10, вам необходимо, чтобы tsl.soбиблиотека была доступна локально. Эту библиотеку можно найти в репозитории TSL на github. Мы также сделали расширение TSL WarpScript доступным в WarpFleet, репозитории расширений сообщества Warp 10.

Чтобы настроить расширение TSL на Warp 10, просто загрузите JAR, указанный в WarpFleet. Затем вы можете настроить расширение в файле конфигурации Warp 10:

warpscript.extensions = io.ovh.metrics.warp10.script.ext.tsl.TSLWarpScriptExtension
warpscript.tsl.libso.path = <PATH_TO_THE_tsl.so_FILE>


После перезагрузки Warp 10 все готово. Вы можете проверить, работает ли он, выполнив следующий запрос:

// You will need to put here a valid Warp10 token when computing a TSL select statement
// '<A_VALID_WARP_10_TOKEN>' 

// A valid TOKEN isn't needed on the create series statement in this example
// You can simply put an empty string
''

// Native TSL create series statement
 <'
    create(series('test').setValues("now", [-5m, 2], [0, 1])) 
'>
TSL


С помощью функции WarpScript TSL вы можете использовать собственные переменные WarpScript в своем скрипте, как показано в примере ниже:

// Set a Warp10 variable

NOW 'test' STORE

'' 

// A Warp10 variable can be reused in TSL script as a native TSL variable
 <'
    create(series('test').setValues("now", [-5m, 2], [0, 1])).add(test)
'>
TSL


TSL WASM

Чтобы расширить возможности использования TSL, мы также экспортировали его как библиотеку Wasm, так что вы можете использовать ее прямо в браузере! Версия библиотеки Wasm анализирует запросы TSL локально и генерирует WarpScript. Затем результат можно использовать для запроса к бэкэнду Warp 10. Более подробную информацию вы найдете на github TSL.

Новые возможности TSL

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

Мы добавили setLabelFromNameметод, чтобы установить новую метку для серии на основе ее имени. Эта метка может быть точным названием серии или результатом регулярного выражения.

Мы также доработали sortметод, позволяющий пользователям сортировать набор серий на основе метаданных серии (т. Е. Селектора, имени или меток).

Наконец, мы добавили filterWithoutLabels, чтобы отфильтровать набор серий и удалить все серии, не содержащие конкретных меток.

Спасибо за прочтение! Я надеюсь, что вы попробуете TSL, так как я хотел бы услышать ваши отзывы.

Встреча в Париже Time Series

Мы рады провести в парижском офисе OVHcloud третью встречу Paris Time Series, организованную Николасом Штайнметцем. Во время этой встречи мы поговорим о TSL, а также познакомимся с платформой Redis Times Series.

Если вы свободны, мы будем рады встретить вас там!

IOT: передача данных в таймсерии метрик OVHcloud из Arduino



Прошлой весной я построил в своем саду дровяную печь. Я хотел иметь такую ​​много лет, и наконец решил ее создать. Чтобы использовать его, я разжигаю внутри большой огонь на два часа, удаляю все угли, и тогда он готов к приготовлению. Духовка накапливает тепло во время огня, а затем отдает его.

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

  • Пицца: 280 ° C
  • Хлеб: 250 ° C
  • Рисовый пудинг: 180 ° C
  • Безе: 100 ° C



Я построил первую версию термометра с Arduino, чтобы иметь возможность проверять температуру. Этот термометр, сделанный из термопары (т. Е. Датчика, который измеряет высокие температуры), отображает внутреннюю температуру на маленьком ЖК-экране.



Следующим шагом было предвидеть, когда начинать посуду в духовке. Наблюдать за падением температуры в течение нескольких часов было плохой идеей. Мне нужна была тепловая диаграмма моей духовки! Тепловая диаграмма — это просто диаграмма температуры за определенный период времени. Но записывать температуру на бумаге каждые десять минут… подождите… этого хватит на 30 часов.



Пожалуйста, дайте мне поспать!

Это требует некоторой автоматизации. К счастью, у OVHcloud есть решение: платформа данных метрик: www.ovh.com/fr/data-platforms/metrics/

Оборудование

Цель проекта — подключить датчик к Arduino, который будет отправлять данные на платформу данных метрик OVHcloud ( www.ovh.com/fr/data-platforms/metrics/ ) по сети. По сути, Arduino будет использовать локальную сеть Wi-Fi для передачи данных о температуре на серверы OVHcloud.

Вы знаете ESP8266? Это недорогой ( менее 2 евро! ) Микрочип Wi-Fi с полным стеком TCP / IP и возможностями микроконтроллера.



Функциональная схема ESP8266



Реализация: Wemos

ESP8266 не так прост в использовании сам по себе:

  • Должен быть запитан от 3,3 В (не слишком много, иначе он сгорит)
  • Нет USB



Поэтому лучше использовать решение, реализующее для нас ESP8266. Вот Wemos!

  • Питание от 5 В (6 В все еще в порядке)
  • USB для последовательной связи (для отладки)
  • Программирование через USB
  • Может быть запрограммирован с помощью Arduino IDE
  • Стоит меньше 3 €

Подготовьте свою Arduino IDE

Установите интегрированную среду разработки

Прежде всего вам необходимо установить Arduino IDE. Это бесплатно и доступно для любой платформы (Mac, Windows, Linux). Перейдите на www.arduino.cc/en/main/software и загрузите версию, соответствующую вашей платформе. На момент написания текущая версия — 1.8.10.



Дополнительная конфигурация для ESP8266

Когда вы установите Arduino IDE, она сможет программировать только официальные Arduinos. Добавим прошивку и библиотеки для ESP8266…



Запустите Arduino и откройте окно «Настройки» ( Файл> Настройки ).
Введите
<a href="https://arduino.esp8266.com/stable/package_esp8266com_index.json" target="_blank" rel="nofollow external noopener noreferrer" data-wpel-link="external">https://arduino.esp8266.com/stable/package_esp8266com_index.json</a>
 в поле «Дополнительные URL-адреса Board Manager». Вы можете добавить несколько URL-адресов, разделяя их запятыми.

Теперь откройте «Менеджер плат» в меню « Инструменты»> « Плата» и установите платформу esp8266 (не забудьте выбрать плату ESP8266 в меню « Инструменты»> « Плата» после установки).



Теперь вы готовы!

Заказать платформу данных метрик

Перейдите на веб-сайт платформы данных метрик OVHcloud: www.ovh.com/fr/data-platforms/metrics/. Нажмите на бесплатную пробную версию и завершите свой заказ. Если у вас нет учетной записи, просто создайте ее. В этом испытании у вас будет 12 показателей (т. Е. 12 наборов записей). В этом примере мы будем использовать только один.



Получите свой токен

Перейдите в панель управления OVH: www.ovh.com/manager/cloud/#/. На левой панели у вас должны быть метрики и новый сервис внутри.



Во вкладке «Токены» вы можете скопировать токен записи. Сохраните его, так как он нам понадобится позже.



Обратите внимание, что для настройки Grafana вам понадобится токен чтения.

Получить хост платформы данных метрик

Хост вашей платформы данных метрик указан в описании вашей услуги. На вкладке «Платформы» скопируйте хост opentsdb. Сохраните его, так как он нам понадобится позже.



Глубже в программе

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


  • Попробуйте подключиться к вашей сети Wi-Fi
  • В случае успеха отправьте данные в платформу данных метрик OVHcloud

Весь исходный код доступен на моем github: https://github.com/landru29/ovh_metrics_wemos .

Есть шесть основных файлов:
  • ovh_metrics_wemos.ino : главный файл
  • wifi.cpp : класс, который реализует процесс подключения к Wi-Fi через WPS (Wifi Protected Setup)
  • wifi.h : заголовочный файл для Wi-Fi
  • metrics.cpp : класс, который отправляет данные метрики в платформу данных метрик OVHcloud через HTTPS.
  • metrics.h : заголовочный файл для показателей
  • config.h.sample : модель для создания файла конфигурации (см. ниже)

Создайте свой файл конфигурации

Если вы попытаетесь скомпилировать программу, вы получите ошибки, так как некоторые определения отсутствуют. Нам нужно объявить их в файле config.h .
  1. Скопируйте config.h.sample в config.h
  2. Скопируйте токен записи, полученный в пункте 5.1 (#define TOKEN «xxxxxx»)
  3. Скопируйте хост, указанный в параграфе 5.2 (#define HOST «xxxxxx»).

Получите отпечаток сертификата

Поскольку Wemos будет запрашивать через HTTPS, нам понадобится отпечаток сертификата. Вам понадобится хост, который вы только что взяли на вкладке «Платформы», а затем:

Пользователи Linux
Просто запустите этот небольшой скрипт:

HOST=opentsdb.gra1.metrics.ovh.net; echo | openssl s_client -showcerts -servername ${HOST} -connect ${HOST}:443 2>/dev/null | openssl x509 -noout -fingerprint -sha1 -inform pem | sed -e "s/.*=//g" | sed -e "s/\:/ /g"


Скопируйте результат в свой
.config.h (#define FINGERPRINT "xx xx ..")


Пользователи MAC
Просто запустите этот небольшой скрипт:

HOST=opentsdb.gra1.metrics.ovh.net; echo | openssl s_client -showcerts -servername ${HOST} -connect ${HOST}:443 2>/dev/null | openssl x509 -noout -fingerprint -sha1 -inform pem | sed -e "s/.*=//g" | sed -e "s/\:/ /g"


Скопируйте результат в свой
.config.h (#define FINGERPRINT "xx xx ..")


Пользователи Windows

В своем браузере перейдите на opentsdb.gra1.metrics.ovh.net. Нажмите на замок рядом с URL-адресом, чтобы отобразить отпечаток сертификата. Замените все ":" одним пробелом.

Скомпилируйте проект и загрузите его в Wemos

  1. Откройте
    .ino
     файл в Arduino IDE (у вас в проекте должно быть шесть вкладок)
  2. Подключите Wemos к вашему компьютеру
  3. Выберите порт из Инструменты> Порт
  4. В верхнем левом углу нажмите на стрелку, чтобы загрузить программу.
  5. После загрузки вы можете открыть монитор последовательного порта: Инструменты> Монитор последовательного порта

Прямо сейчас программа должна выйти из строя, поскольку Wemos не сможет подключиться к вашей сети Wi-Fi.

Запустите программу

Как мы уже видели, при первом запуске происходит сбой. Это потому, что вам нужно запустить WPS-соединение, поэтому в зависимости от вашего интернет-модема вам нужно будет запустить транзакцию WPS. Это может быть физическая кнопка на модеме или программное действие, запускаемое на консоли ( en.wikipedia.org/wiki/Wi-Fi_Protected_Setup ).

Когда процесс запускается на стороне модема, у вас есть примерно 30 секунд для включения Wemos.

  1. Подключите Wemos через USB => программа запущена
  2. Выберите порт из  Инструменты> Порт  (возможно, он изменился)
  3. Откройте последовательный монитор:  Инструменты> Последовательный монитор.

Теперь вы можете следить за процессом.

Wi-Fi соединение

В последовательном мониторе (установите битрейт 9600) вы должны получить:

Try to connect
 
WPS config start
Trying to connect to <your modem> with saved config ...|SUCCESS
IP address: 192.168.xx.xx


Если соединение Wi-Fi было успешным, последовательная консоль должна отображать локальный IP-адрес (192.168.xx.xx), в противном случае — сбой. Попробуйте еще раз, запустив WPS на модеме и перезапустив Wemos (отключите его и снова подключите).

Отправка данных в платформу данных метрик OVHcloud

Теперь Wemos отправляет запрос на сервер OVHcloud. Последовательная консоль показывает вам отправленный JSON:

------------------------------------------------
POST opentsdb.gra1.metrics.ovh.net/api/put
[{"metric": "universe","value":42,"tags":{}}]
------------------------------------------------
beginResult: 0
http: 204
response: xxxx


Если beginResult отрицательный, соединение с сервером OVHcloud не удалось. Это могло означать, что FINGERPRINT это неправильно.

Если http нет 2xx (должно быть 204), сервер не может обработать ваш запрос. Это может означать, что TOKEN это неправильно.

У вас есть 204? Большой! Это успех. Давайте проверим это на Grafana…

Настроить Grafana

Перейдите на сайт OVHcloud Grafana: grafana.metrics.ovh.net/login. Войдите в свою учетную запись OVHcloud.



Настроить источник данных

Щелкните «Добавить источник данных».



  • Имя : выберите одно
  • Тип : OpenTSDB
  • URL : https: // <хост, полученный от вашего менеджера (см. Ниже)>
  • Доступ : прямой
  • Установите флажок «Обычная аутентификация»
  • Пользователь : метрики
  • Пароль : <Прочитать токен у вашего менеджера (см. Ниже)>

Нажмите кнопку «Добавить»…



… И сохраните его.

Создайте свою первую диаграмму

Вернитесь на grafana.metrics.ovh.net/ и нажмите «Новая панель управления».



Щелкните «График».



Щелкните «Заголовок панели», затем «Изменить».



Выберите свой показатель в поле «Название показателя». Программное обеспечение должно предлагать имя Universe (имя, указанное в программе Arduino). Если это не так, это означает, что показатели были отправлены Wemos неправильно. Закройте панель «редактирования» (щелкните крестик справа) и сохраните свою конфигурацию (вверху слева в окне).

Анализ результатов

Повышение температуры

Первый результат, который нужно проанализировать, — это повышение температуры. Датчик лежал на кирпичах духовки. Желтая диаграмма — это температура духового шкафа, а зеленая диаграмма — температура окружающей среды.

  1. Между 11:05 и 11:10 есть шаг около 85 ° C. Кажется, это влага сушившей духовки.
  2. Затем происходит падение температуры, поэтому я добавил еще дров в духовку (то есть добавил холод).
  3. Примерно в 11:20 наклон полегче, и я не знаю почему. Огонь недостаточно сильный? В кирпиче больше влаги?



Выпадающее меню температуры

На этом этапе я переместил все угли в задней части духовки и поместил датчик там, где горел огонь. Вот почему диаграмма начинается с 400 ° C.

  1. Падение температуры выглядит как F (t) = A / t
  2. Примерно в 15:40 я сменил блок питания с телефона, подключенного к сети 230 В, на автомобильный аккумулятор с регулятором напряжения (что показалось хреновым)
  3. С 15:00 до 17:00 температура окружающего воздуха довольно высокая. Был солнечный день, поэтому контур напрямую нагревало солнце.

Как отслеживать свой кластер Kubernetes с помощью OVH Observability

Наши коллеги из команды K8S на прошлой неделе запустили решение OVH Managed Kubernetes, в котором они управляют главными компонентами Kubernetes и создают ваши узлы поверх нашего решения Public Cloud. Я не буду описывать здесь детали того, как это работает, но в блогах уже есть много сообщений об этом ( здесь и здесь, чтобы вы начали).

В команде Prescience мы используем Kubernetes уже больше года. Наш кластер включает 40 узлов, работающих поверх PCI. Мы постоянно запускаем около 800 модулей и в результате генерируем множество показателей.

Сегодня мы рассмотрим, как мы обрабатываем эти метрики для мониторинга нашего кластера Kubernetes, и (что не менее важно!) Как это сделать с вашим собственным кластером.

Показатели OVH

Как и в любой другой инфраструктуре, вам необходимо отслеживать свой кластер Kubernetes. Вам необходимо точно знать, как ведут себя ваши узлы, кластер и приложения после их развертывания, чтобы предоставлять надежные услуги вашим клиентам. Чтобы сделать это с нашим собственным кластером, мы используем OVH Observability.

OVH Observability не зависит от серверной части, поэтому мы можем передавать метрики в одном формате и запрашивать в другом. Он может обрабатывать:

  • Graphite
  • InfluxDB
  • Metrics2.0
  • OpentTSDB
  • Prometheus
  • Warp10

Он также включает управляемую Grafana для отображения показателей и создания панелей мониторинга.

Узлы мониторинга

Первое, что нужно контролировать, — это состояние узлов. Все остальное начинается с этого.

Чтобы контролировать ваши узлы, мы будем использовать Noderig и Beamium, как описано здесь. Мы также будем использовать Kubernetes DaemonSets для запуска процесса на всех наших узлах.



Итак, приступим к созданию пространства имен…

kubectl create namespace metrics


Затем создайте секрет с метриками токена записи, которые вы можете найти в панели управления OVH.

kubectl create secret generic w10-credentials --from-literal=METRICS_TOKEN=your-token -n metrics


Скопируйте metrics.ymlв файл и примените конфигурацию с помощью kubectl

metrics.yml
# This will configure Beamium to scrap noderig
# And push metrics to warp 10
# We also add the HOSTNAME to the labels of the metrics pushed
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: beamium-config
  namespace: metrics
data:
  config.yaml: |
    scrapers:
      nodering:
        url: http://0.0.0.0:9100/metrics
        period: 30000
        format: sensision
        labels:
          app: nodering

    sinks:
      warp:
        url: https://warp10.gra1.metrics.ovh.net/api/v0/update
        token: $METRICS_TOKEN

    labels:
      host: $HOSTNAME

    parameters:
      log-file: /dev/stdout
---
# This is a custom collector that report the uptime of the node
apiVersion: v1
kind: ConfigMap
metadata:
  name: noderig-collector
  namespace: metrics
data:
  uptime.sh: |
    #!/bin/sh
    echo 'os.uptime' `date +%s%N | cut -b1-10` `awk '{print $1}' /proc/uptime`
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: metrics-daemon
  namespace: metrics
spec:
  selector:
    matchLabels:
      name: metrics-daemon
  template:
    metadata:
      labels:
        name: metrics-daemon
    spec:
      terminationGracePeriodSeconds: 10
      hostNetwork: true
      volumes:
      - name: config
        configMap:
          name: beamium-config
      - name: noderig-collector
        configMap:
          name: noderig-collector
          defaultMode: 0777
      - name: beamium-persistence
        emptyDir:{}
      containers:
      - image: ovhcom/beamium:latest
        imagePullPolicy: Always
        name: beamium
        env:
        - name: HOSTNAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: TEMPLATE_CONFIG
          value: /config/config.yaml
        envFrom:
        - secretRef:
            name: w10-credentials
            optional: false
        resources:
          limits:
            cpu: "0.05"
            memory: 128Mi
          requests:
            cpu: "0.01"
            memory: 128Mi
        workingDir: /beamium
        volumeMounts:
        - mountPath: /config
          name: config
        - mountPath: /beamium
          name: beamium-persistence
      - image: ovhcom/noderig:latest
        imagePullPolicy: Always
        name: noderig
        args: ["-c", "/collectors", "--net", "3"]
        volumeMounts:
        - mountPath: /collectors/60/uptime.sh
          name: noderig-collector
          subPath: uptime.sh
        resources:
          limits:
            cpu: "0.05"
            memory: 128Mi
          requests:
            cpu: "0.01"
            memory: 128Mi

Не стесняйтесь менять уровни коллектора, если вам нужна дополнительная информация.

Затем примените конфигурацию с помощью kubectl…

$ kubectl apply -f metrics.yml
# Then, just wait a minutes for the pods to start
$ kubectl get all -n metrics
NAME                       READY   STATUS    RESTARTS   AGE
pod/metrics-daemon-2j6jh   2/2     Running   0          5m15s
pod/metrics-daemon-t6frh   2/2     Running   0          5m14s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE AGE
daemonset.apps/metrics-daemon 40        40        40      40           40          122d


Вы можете импортировать нашу панель управления в свою Grafana отсюда и сразу же просматривать некоторые показатели о ваших узлах.



OVH Метрики

Поскольку OVH Kube — это управляемая служба, вам не нужно контролировать apiserver, etcd или панель управления. Об этом позаботится команда OVH Kubernetes. Поэтому мы сосредоточимся на показателях cAdvisor и показателях состояния Kube.

Самым зрелым решением для динамического считывания метрик внутри Kube (на данный момент) является Prometheus.


В следующем выпуске Beamium мы сможем воспроизвести функции скребка Prometheus.


Чтобы установить сервер Prometheus, вам необходимо установить Helm в кластере…

kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller \
    --clusterrole cluster-admin \
    --serviceaccount=kube-system:tiller
helm init --service-account tiller


Затем вам нужно создать следующие два файла: prometheus.yml и values.yml.

# Based on https://github.com/prometheus/prometheus/blob/release-2.2/documentation/examples/prometheus-kubernetes.yml
serverFiles:
  prometheus.yml:
    remote_write:
    - url: "https://prometheus.gra1.metrics.ovh.net/remote_write"
      remote_timeout: 120s
      bearer_token: $TOKEN
      write_relabel_configs:
      # Filter metrics to keep
      - action: keep
        source_labels: [__name__]
        regex: "eagle.*|\
            kube_node_info.*|\
            kube_node_spec_taint.*|\
            container_start_time_seconds|\
            container_last_seen|\
            container_cpu_usage_seconds_total|\
            container_fs_io_time_seconds_total|\
            container_fs_write_seconds_total|\
            container_fs_usage_bytes|\
            container_fs_limit_bytes|\
            container_memory_working_set_bytes|\
            container_memory_rss|\
            container_memory_usage_bytes|\
            container_network_receive_bytes_total|\
            container_network_transmit_bytes_total|\
            machine_memory_bytes|\
            machine_cpu_cores"

    scrape_configs:
    # Scrape config for Kubelet cAdvisor.
    - job_name: 'kubernetes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      
      relabel_configs:
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
        
      metric_relabel_configs:
      # Only keep systemd important services like docker|containerd|kubelet and kubepods,
      # We also want machine_cpu_cores that don't have id, so we need to add the name of the metric in order to be matched
      # The string will concat id with name and the separator is a ;
      # `/;container_cpu_usage_seconds_total` OK
      # `/system.slice;container_cpu_usage_seconds_total` OK
      # `/system.slice/minion.service;container_cpu_usage_seconds_total` NOK, Useless
      # `/kubepods/besteffort/e2514ad43202;container_cpu_usage_seconds_total` Best Effort POD OK
      # `/kubepods/burstable/e2514ad43202;container_cpu_usage_seconds_total` Burstable POD OK
      # `/kubepods/e2514ad43202;container_cpu_usage_seconds_total` Guaranteed POD OK
      # `/docker/pod104329ff;container_cpu_usage_seconds_total` OK, Container that run on docker but not managed by kube
      # `;machine_cpu_cores` OK, there is no id on these metrics, but we want to keep them also
      - source_labels: [id,__name__]
        regex: "^((/(system.slice(/(docker|containerd|kubelet).service)?|(kubepods|docker).*)?);.*|;(machine_cpu_cores|machine_memory_bytes))$"
        action: keep
      # Remove Useless parents keys like `/kubepods/burstable` or `/docker`
      - source_labels: [id]
        regex: "(/kubepods/burstable|/kubepods/besteffort|/kubepods|/docker)"
        action: drop
        # cAdvisor give metrics per container and sometimes it sum up per pod
        # As we already have the child, we will sum up ourselves, so we drop metrics for the POD and keep containers metrics
        # Metrics for the POD don't have container_name, so we drop if we have just the pod_name
      - source_labels: [container_name,pod_name]
        regex: ";(.+)"
        action: drop
    
    # Scrape config for service endpoints.
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

    # Example scrape config for pods
    #
    # The relabeling allows the actual pod scrape endpoint to be configured via the
    # following annotations:
    #
    # * `prometheus.io/scrape`: Only scrape pods that have a value of `true`
    # * `prometheus.io/path`: If the metrics path is not `/metrics` override this.
    # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the
    # pod's declared ports (default is a port-free target if none are declared).
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod

      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: host
      - action: labeldrop
        regex: (pod_template_generation|job|release|controller_revision_hash|workload_user_cattle_io_workloadselector|pod_template_hash)


values.yml
alertmanager:
  enabled: false
pushgateway:
  enabled: false
nodeExporter:
  enabled: false
server:
  ingress:
    enabled: true
    annotations:
      kubernetes.io/ingress.class: traefik
      ingress.kubernetes.io/auth-type: basic
      ingress.kubernetes.io/auth-secret: basic-auth
    hosts:
    - prometheus.domain.com
  image:
    tag: v2.7.1
  persistentVolume:
    enabled: false


Не забудьте заменить свой токен!

Скребок Прометей довольно мощный. Вы можете изменить метку своего временного ряда, оставить несколько, которые соответствуют вашему регулярному выражению, и т. Д. Эта конфигурация удаляет множество бесполезных метрик, поэтому не стесняйтесь настраивать его, если вы хотите увидеть больше метрик cAdvisor (например).

Установите его с помощью Helm…

helm install stable/prometheus \
    --namespace=metrics \
    --name=metrics \
    --values=values/values.yaml \
    --values=values/prometheus.yaml


Добавить добавить секрет базовой аутентификации…

$ htpasswd -c auth foo
New password: <bar>
New password:
Re-type new password:
Adding password for user foo
$ kubectl create secret generic basic-auth --from-file=auth -n metrics
secret "basic-auth" created


Вы можете получить доступ к интерфейсу сервера Prometheus через prometheus.domain.com.



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

Интерфейсы Prometheus — хороший способ изучить ваши метрики, поскольку довольно просто отображать и контролировать вашу инфраструктуру. Вы можете найти нашу панель управления здесь.



Метрики ресурсов

Как сказал @ Martin Schneppenheim в этом посте, для правильного управления кластером Kubernetes вам также необходимо отслеживать ресурсы пода.

Мы установим Kube Eagle, который будет извлекать и предоставлять некоторые метрики о запросах и ограничениях ЦП и ОЗУ, чтобы они могли быть получены только что установленным сервером Prometheus.



Создайте файл с именем eagle.yml.

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  labels:
    app: kube-eagle
  name: kube-eagle
  namespace: kube-eagle
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  - pods
  verbs:
  - get
  - list
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  labels:
    app: kube-eagle
  name: kube-eagle
  namespace: kube-eagle
subjects:
- kind: ServiceAccount
  name: kube-eagle
  namespace: kube-eagle
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-eagle
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: kube-eagle
  labels:
    app: kube-eagle
  name: kube-eagle
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-eagle
  name: kube-eagle
  labels:
    app: kube-eagle
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-eagle
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/metrics"
      labels:
        app: kube-eagle
    spec:
      serviceAccountName: kube-eagle
      containers:
      - name: kube-eagle
        image: "quay.io/google-cloud-tools/kube-eagle:1.0.0"
        imagePullPolicy: IfNotPresent
        env:
        - name: PORT
          value: "8080"
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: http
        readinessProbe:
          httpGet:
            path: /health
            port: http


$ kubectl create namespace kube-eagle
$ kubectl apply -f eagle.yml


Затем добавьте импорт этой панели управления Grafana (это та же панель, что и Kube Eagle, но перенесена на Warp10).



Теперь у вас есть простой способ контролировать ресурсы вашего модуля в кластере!

Пользовательские показатели

Как Прометей узнает, что ему нужно соскрести куба-орла? Если вы посмотрите на метаданные eagle.yml, вы увидите, что:

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "8080" # The port where to find the metrics
  prometheus.io/path: "/metrics" # The path where to find the metrics


Эти аннотации запустят процесс автоматического обнаружения Prometheus (описанный в prometheus.ymlстроке 114).

Это означает, что вы можете легко добавить эти аннотации к модулям или службам, которые содержат экспортер Prometheus, а затем пересылать эти метрики в OVH Observability. Вы можете найти неполный список экспортеров Прометея здесь.



Объемный анализ

Как вы видели на странице prometheus.yml, мы попытались отфильтровать множество бесполезных показателей. Например, cAdvisor в новом кластере, всего с тремя настоящими производственными модулями, а также со всей системой kube и пространством имен Prometheus, имеет около 2600 метрик на узел. Используя интеллектуальный подход к очистке, вы можете сократить это количество до 126 серий.

Вот таблица, показывающая приблизительное количество метрик, которые вы создадите, в зависимости от количества узлов (N) и количества производственных модулей (P), которые у вас есть:



Например, если вы запустите три узла с 60 подами, вы сгенерируете 264 * 3 + 32 * 60 ~ = 2700 метрик.

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

(1) Метрики Noderig: os.mem / os.cpu / os.disk.fs / os.load1 / os.net.dropped (in/out) / os.net.errs (in/out) / os.net.packets (in/out) / os.net.bytes (in/out)/ os.uptime

(2) метрики узлов cAdvisor: machine_memory_bytes / machine_cpu_cores

(3) Метрики узлов состояния Kube: kube_node_info

(4) Показатели узлов Kube Eagle: eagle_node_resource_allocatable_cpu_cores / eagle_node_resource_allocatable_memory_bytes / eagle_node_resource_limits_cpu_cores / eagle_node_resource_limits_memory_bytes / eagle_node_resource_requests_cpu_cores / eagle_node_resource_requests_memory_bytes / eagle_node_resource_usage_cpu_cores / eagle_node_resource_usage_memory_bytes

(5) С помощью наших фильтров мы будем отслеживать около пяти system.slices.

(6) Показатели указываются для каждого контейнера. Pod — это набор контейнеров (минимум два): ваш контейнер + контейнер паузы для сети. Таким образом, мы можем рассматривать (2 * 10 + 6) для количества метрик в пакете. 10 показателей из cAdvisor и шесть для сети (см. Ниже) и для system.slice у нас будет 10 + 6, потому что он рассматривается как один контейнер.

(7) cAdvisor предоставит следующие показатели для каждого контейнера :container_start_time_seconds / container_last_seen / container_cpu_usage_seconds_total / container_fs_io_time_seconds_total / container_fs_write_seconds_total / container_fs_usage_bytes / container_fs_limit_bytes / container_memory_working_set_bytes / container_memory_rss / container_memory_usage_bytes

(8) cAdvisor предоставит следующие показатели для каждого интерфейса: container_network_receive_bytes_total * per interface / container_network_transmit_bytes_total * per interface

(9) kube-dns / beamium-noderig-metrics / kube-proxy / canal / metrics-server

(10) Показатели модулей Kube Eagle: eagle_pod_container_resource_limits_cpu_cores / eagle_pod_container_resource_limits_memory_bytes / eagle_pod_container_resource_requests_cpu_cores / eagle_pod_container_resource_requests_memory_bytes / eagle_pod_container_resource_usage_cpu_cores / eagle_pod_container_resource_usage_memory_bytes

Вывод

Как видите, отслеживать кластер Kubernetes с помощью OVH Observability очень просто. Вам не нужно беспокоиться о том, как и где хранить свои метрики, и вы можете сосредоточиться на использовании кластера Kubernetes для эффективной обработки бизнес-нагрузок, как это делаем мы в группе обслуживания машинного обучения.

Следующим шагом будет добавление системы предупреждений, чтобы уведомить вас, когда ваши узлы не работают (например). Для этого вы можете использовать бесплатный инструмент OVH Alert Monitoring.

Рекомендации по мониторингу наблюдаемости OVH

В команде OVH Observability (ранее Metrics) мы собираем, обрабатываем и анализируем большую часть данных мониторинга OVH. Он представляет около 500 миллионов уникальных показателей, перемещая точки данных с постоянной скоростью 5 миллионов в секунду.

Эти данные можно классифицировать двумя способами: мониторинг хоста или приложения. Мониторинг хоста в основном основан на аппаратных счетчиках (ЦП, память, сеть, диск…), тогда как мониторинг приложений основан на сервисе и его масштабируемости (запросы, обработка, бизнес-логика…).

Мы предоставляем эту услугу для внутренних команд, которые пользуются тем же опытом, что и наши клиенты. По сути, наша служба Observability — это SaaS с уровнем совместимости (поддерживающим InfluxDB, OpenTSDB, Warp10, Prometheus и Graphite), который позволяет ему интегрироваться с большинством существующих решений. Таким образом, команде, которая привыкла к определенному инструменту или уже развернула решение для мониторинга, не нужно будет тратить много времени или усилий при переходе на полностью управляемую и масштабируемую службу: они просто выбирают токен, используют правильный конечная точка, и все готово. Кроме того, наш уровень совместимости предлагает выбор: вы можете отправить свои данные с помощью OpenTSDB, а затем запросить их в PromQL или WarpScript. Подобное комбинирование протоколов приводит к уникальной совместимости с открытым исходным кодом, которая обеспечивает большую ценность.

Scollector, Snap, Telegraf, Graphite, Collectd…

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

В OVH мы используем наборы показателей, вырезанные лазером. У каждого хоста есть определенный шаблон (веб-сервер, база данных, автоматизация…), который экспортирует заданное количество показателей, которые можно использовать для диагностики работоспособности и мониторинга производительности приложений.

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

Beamium & Noderig — Идеальная посадка

Наши требования были довольно простыми:
Масштабируемость : мониторинг одного узла так же, как мы наблюдаем за тысячами
Laser-Cut : собирать только релевантные метрики
Надежность : мы хотим, чтобы метрики были доступны даже в наихудших условиях
Просто : Несколько компонентов plug-and-play вместо сложных
Эффективность : мы верим в беспроблемный сбор показателей

Первым решением был Beamium

Beamium обрабатывает два аспекта процесса мониторинга: данные приложения слом и показатели пересылки.

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

Источники, из которых Beamium будет извлекать данные, — это просто конечные точки HTTP Prometheus. Это означает, что это так же просто, как предоставить конечную точку HTTP и, в конечном итоге, добавить несколько параметров. Эти данные будут направляться в приемники, что позволяет нам фильтровать их во время процесса маршрутизации между источником и приемником. Приемники — это конечные точки Warp 10 ®, куда мы можем отправлять данные.

После очистки метрики сначала сохраняются на диске, а затем направляются в приемник. Механизм переключения диска при отказе (DFO) позволяет выполнять восстановление после сбоя в сети или удаленно. Таким образом, локально мы сохраняем логику вытягивания Prometheus, но децентрализованно, и мы обращаем ее вспять, чтобы протолкнуть для подачи на платформу, которая имеет много преимуществ:

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

У нас много разных клиентов, некоторые из которых используют хранилище временных рядов для продукта Observability для управления потреблением продукта или транзакционными изменениями при лицензировании. Эти варианты использования не могут быть обработаны с помощью экземпляров Prometheus, которые лучше подходят для мониторинга на основе метрик.



Второй был Noderig

В ходе бесед с некоторыми из наших клиентов мы пришли к выводу, что существующие инструменты нуждаются в определенном уровне знаний, чтобы их можно было использовать в больших масштабах. Например, команда с кластером из 20 тыс. Узлов с Scollector в итоге получит более 10 миллионов метрик только для узлов… Фактически, в зависимости от конфигурации оборудования, Scollector будет генерировать от 350 до 1000 метрик из одного узла.

Это причина создания Noderig. Мы хотели, чтобы он был таким же простым в использовании, как экспортер узлов от Prometheus, но с более детализированным производством метрик по умолчанию.

Noderig собирает метрики ОС (ЦП, память, диск и сеть), используя семантику простого уровня. Это позволяет собирать нужное количество метрик для любого типа хоста, что особенно подходит для контейнерных сред.

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

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



Это работает?

Beamium и Noderig широко используются в OVH и поддерживают мониторинг очень больших инфраструктур. На момент написания мы собираем и храним сотни миллионов показателей с помощью этих инструментов. Так что они определенно работают!

Фактически, в настоящее время мы работаем над выпуском 2.0, который будет доработкой, включающей автообнаружение и горячую перезагрузку.

TSL: удобный для разработчиков язык запросов временных рядов для всех наших показателей

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

TSL означает язык временных рядов . Проще говоря, TSL  — это абстрактный способ генерации запросов для различных бэкэндов TSDB в форме HTTP-прокси. В настоящее время он поддерживает языки запросов WarpScript 10 и Prometheus PromQL, но мы стремимся расширить поддержку и на другие основные TSDB.



Чтобы предоставить некоторый контекст вокруг того, почему мы создали TSL, он начался с обзора некоторых языков запросов TSDB, поддерживаемых  платформой данных метрик OVH . Реализуя их, мы узнали хорошее, плохое и уродливое в каждом из них. В конце концов, мы решили создать TSL, чтобы упростить выполнение запросов на нашей платформе, прежде чем открывать его для использования в любом решении TSDB. 

Так почему мы решили потратить время на разработку такого прокси? Что ж, позвольте мне рассказать вам историю протокола OVH Metrics !

Из OpenTSDB…



Первая цель нашей платформы — обеспечить поддержку инфраструктуры OVH и мониторинга приложений. Когда этот проект стартовал, многие люди использовали OpenTSDB и были знакомы с его синтаксисом запросов. OpenTSDB  — это масштабируемая база данных для временных рядов. Запрос OpenTSDB синтаксис легко читается, как вы отправить JSON документ , описывающий запрос. Ниже документ будет загружать все 
sys.cpu.0
 метрики в 
test
центре обработки данных, суммируя их между 
start
 и 
end
датами:

{
    "start": 1356998400,
    "end": 1356998460,
    "queries": [
        {
            "aggregator": "sum",
            "metric": "sys.cpu.0",
            "tags": {
                "host": "*",
                "dc": "test"
            }
        }
    ]
}


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

OpenTSDB был первым протоколом, поддерживаемым командой Metrics, и до сих пор широко используется. Внутренняя статистика показывает, что 30-40% нашего трафика основано на запросах OpenTSDB. Многие внутренние сценарии использования все еще могут быть полностью решены с помощью этого протокола, а запросы легко писать и понимать.

Например, запрос с OpenTSDB для получения максимального значения 
usage_system
для диапазона от 
cpu
0 до 9, взятого за 2-минутный интервал по среднему их значению, выглядит следующим образом:

{
    "start": 1535797890,
    "end": 1535818770,
    "queries":  [{
        "metric":"cpu.usage_system",
        "aggregator":"max",
        "downsample":"2m-avg",
        "filters": [{
            "type":"regexp",
            "tagk":"cpu",
            "filter":"cpu[0–9]+",
            "groupBy":false
            }]
        }]
}


Однако OpenTSDB быстро показывает свои ограничения, и некоторые конкретные случаи использования не могут быть решены с его помощью. Например, вы не можете применять какие-либо операции непосредственно на сервере. Вы должны загрузить данные во внешний инструмент и использовать его для применения любой аналитики.

Одна из основных областей, в которых отсутствует OpenTSDB (версия 2.3), — это несколько операторов набора временных рядов, которые позволяют выполнять такие действия, как разделение ряда. Эти операторы могут быть полезным способом вычисления времени отдельного запроса для каждого запроса, когда у вас есть (например) набор общего времени, затраченного на запросы, и набор рядов общего количества запросов. Это одна из причин, почему платформа данных метрик OVH поддерживает другие протоколы.

… В PromQL



Вторым протоколом, над которым мы работали, был PromQL , язык запросов к базе данных временных рядов Prometheus . Когда мы сделали этот выбор в 2015 году, Prometheus набирал обороты, и у него по-прежнему впечатляющие темпы внедрения. Но если Prometheus добился успеха, дело не в его языке запросов, PromQL. Этот язык так и не получил широкого распространения внутри компании, хотя в последнее время он начал получать некоторое распространение, в основном благодаря приходу людей, которые работали с Prometheus в своих предыдущих компаниях. На внутреннем уровне запросы PromQL составляют около 1-2%нашего ежедневного трафика. Основные причины заключаются в том, что многие простые варианты использования могут быть решены быстро и с большим контролем необработанных данных с помощью запросов OpenTSDB, в то время как многие более сложные варианты использования не могут быть решены с помощью PromQL. Запрос, аналогичный тому, что определен в OpenTSDB, будет выглядеть так:

api/v1/query_range?
query=max(cpu. usage_system{cpu=~"cpu[0–9]%2B"})
start=1535797890&
end=1535818770&
step=2m


Используя PromQL, вы теряете контроль над выборкой данных , поскольку единственный оператор остается последним . Это означает, что если (например) вы хотите уменьшить частоту дискретизации своей серии до 5-минутной продолжительности, вы можете сохранить только последнее значение каждого 5-минутного диапазона. Напротив, у всех конкурентов есть ряд операторов. Например, с OpenTSDB вы можете выбирать между несколькими операторами, включая среднее значение, счетчик, стандартное отклонение, первое, последнее, процентили, минимальное, максимальное или суммирование всех значений в пределах определенного диапазона.

В конце концов, многие люди предпочитают использовать гораздо более сложный метод: WarpScript, который работает на движке Warp10 Analytics Engine, который мы используем за кулисами.

Наше внутреннее принятие WarpScript



WarpScript  — это текущий язык временных рядов Warp 10 ® , нашего базового интерфейса. WarpScript поможет в любом сложном случае использования временных рядов и решит множество реальных проблем, так как вы полностью контролируете все свои операции. У вас есть специальные функциональные рамки для выборки необработанных данных и заполнения недостающих значений. У вас также есть платформы для применения операций к однозначным или оконным операциям. Вы можете применять операции к нескольким наборам временных рядов и иметь специальные функции для управления временем временных рядов, статистикой и т. Д.

Он работает с обратной польской нотацией (например, старый добрый HP48, для тех, у кого он есть!), И простые варианты использования могут быть легко описаны. Но когда дело доходит до аналитики, хотя она, безусловно, решает проблемы, ей все еще сложно научиться. В частности, варианты использования временных рядов сложны и требуют модели мышления, поэтому WarpScript помог решить множество сложных задач.

Вот почему он по-прежнему является основным запросом, используемым в OVH на платформе OVH Metrics, при этом почти 60% внутренних запросов используют его. Тот же запрос, который мы только что вычислили в OpenTSDB и PromQL, в WarpScript будет выглядеть следующим образом:

[ "token" "cpu.average" { "cpu" "~cpu[0–9]+" } NOW 2 h ] FETCH
[ SWAP bucketizer.mean 0 2 m 0 ] BUCKETIZE
[ SWAP [ "host" ] reducer.max ] REDUCE


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

Что мы узнали из WarpScript, так это то, что это фантастический инструмент для построения аналитики наших данных Metrics. Мы продвинули множество сложных вариантов использования с помощью передовых алгоритмов обработки сигналов, таких как LTTB , обнаружение выбросов или шаблонов , а также сглаживание ядра, где это оказалось реальным инструментом. Однако поддержка основных требований оказалась довольно дорогой, и отзывы показали, что синтаксис и общая сложность вызывают большие опасения.

WarpScript может включать в себя десятки (или даже сотни) строк, и успешное выполнение часто является достижением с особым чувством, которое возникает от использования в полной мере своих умственных способностей. Фактически, внутренняя шутка среди нашей команды — это способность написать WarpScript за один день или заработать значок WarpScript Pro Gamer! Вот почему мы раздали футболки Metrics пользователям, добившимся значительных успехов с платформой Metrics Data Platform.

Нам понравилась семантика WarpScript, но мы хотели, чтобы она оказала значительное влияние на более широкий спектр вариантов использования. Вот почему мы начали писать TSL с несколькими простыми целями:

  • Предложите четкую семантику аналитики временных рядов
  • Упростите написание и сделайте его удобным для разработчиков
  • Поддержка запросов потока данных и простота отладки сложных запросов
  • Не пытайтесь быть лучшим ящиком для инструментов. Будь проще.

Мы знаем, что пользователям, вероятно, придется время от времени возвращаться к WarpScript. Однако мы надеемся, что использование TSL упростит их обучение. TSL — это просто новый шаг в приключении временных рядов!

Путь к TSL



TSL является результатом трехлетней поддержки аналитики временных рядов и предлагает функциональный язык временных рядов. Целью TSL является построение потока данных временных рядов в виде кода.

В TSL существуют собственные методы, такие как 
select
и 
where
, чтобы выбрать, с какими метриками работать. Затем, поскольку данные временных рядов связаны со временем, мы должны использовать метод выбора времени для выбранной меты. Доступны два метода: 
from
и 
last
. Подавляющее большинство других методов TSL принимают наборы временных рядов в качестве входных данных и предоставляют наборы временных рядов в качестве результата. Например, у вас есть методы, которые выбирают только значения выше определенного порога, скорости вычислений и т. Д. Мы также включили определенные операции для применения к нескольким подмножествам наборов временных рядов в виде сложения или умножения.

Наконец, для более удобочитаемого языка вы можете определить переменные для хранения запросов временных рядов и повторно использовать их в своем скрипте в любое время, когда захотите. На данный момент мы поддерживаем только несколько родных типов, таких как 
Numbers
Strings
Time durations
Lists
и 
Time Series
(конечно же !).

Наконец, тот же запрос, который используется в этой статье, будет выглядеть в TSL следующим образом:

select("cpu.usage_system")
.where("cpu~cpu[0–9]+")
.last(12h)
.sampleBy(2m,mean)
.groupBy(max)


Вы также можете писать более сложные запросы. Например, мы собрали наш практический опыт WarpScript, предназначенный для обнаружения экзопланет по необработанным данным НАСА, в один запрос TSL:

sample = select('sap.flux')
 .where('KEPLERID=6541920')
 .from("2009–05–02T00:56:10.000000Z", to="2013–05–11T12:02:06.000000Z")
 .timesplit(6h,100,"record")
 .filterByLabels('record~[2–5]')
 .sampleBy(2h, min, false, "none")

trend = sample.window(mean, 5, 5)

sub(sample,trend)
 .on('KEPLERID','record')
 .lessThan(-20.0)


Итак, что мы здесь сделали? Сначала мы создали образец переменной, в которую загрузили необработанные данные sap.flux одной звезды, 6541920. Затем мы очистили серию, используя функцию временного разделения (чтобы разделить серию звезд, когда в данных есть дыра с длина больше 6h), сохраняя только четыре записи. Наконец, мы сделали выборку результата, сохранив минимальное значение каждого двухчасового периода.

Затем мы использовали этот результат для вычисления тренда ряда, используя скользящее среднее за 10 часов.

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

TSL с открытым исходным кодом

Даже если наше первое сообщество пользователей было в основном внутри OVH, мы вполне уверены, что TSL можно использовать для решения множества вариантов использования временных рядов.

В настоящее время мы проводим бета-тестирование TSL на нашей публичной платформе OVH Metrics. Кроме того, исходный код TSL на Github открыт , поэтому вы также можете протестировать его на своих собственных платформах.

Мы хотели бы получить ваши отзывы или комментарии о TSL или временных рядах в целом. Мы доступны в сетке метрик OVH, и вы можете узнать больше о TSL в нашей документации по бета-функциям .

Обработка предупреждений OVH с помощью Apache Flink

OVH в значительной степени полагается на метрики для эффективного мониторинга всего своего стека. Независимо от того, являются ли они низкоуровневыми или ориентированными на бизнес , они позволяют командам получить представление о том, как наши службы работают на повседневной основе. Необходимость хранить миллионы точек данных в секунду привела к необходимости создать специальную команду для создания продукта, способного справиться с этой нагрузкой: Metrics Data Platform .  Опираясь на Apache Hbase , Apache Kafka и Warp 10 , нам удалось создать полностью распределенную платформу, которая обрабатывает все наши показатели… и ваши!

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



Встречайте OMNI, наш уровень оповещения

OMNI наше кодовое название  полностью распределенной ,  как-код ,  предупреждая  систему , которую мы разработали на вершине Метрики. Он разделен на компоненты:
  • Часть управления , которая берет определения ваших предупреждений, определенных в репозитории Git, и представляет их как непрерывные запросы,
  • Исполнитель запросов, распределяющий ваши запросы по расписанию.

Исполнитель запроса помещает результаты запроса в Kafka, готовые к обработке! Теперь нам нужно выполнить все задачи, которые выполняет система оповещения:
  • Обработка дедупликации и группировки предупреждений, чтобы избежать усталости от предупреждений. 
  • Обработка шагов эскалации , подтверждения  или откладывания .
  • Уведомить конечного пользователя по разным каналам : SMS, почта, Push-уведомления и т. Д.


Чтобы справиться с этим, мы посмотрели на проекты с открытым исходным кодом, такие как Prometheus AlertManager,  LinkedIn Iris, и обнаружили скрытую правду:


Обработка предупреждений как потоков данных,
передача от оператора к другому.


Мы приняли это и решили использовать Apache Flink для создания Beacon . В следующем разделе мы собираемся описать архитектуру Beacon, а также то, как мы ее построили и эксплуатировали.
Если вам нужна дополнительная информация об Apache Flink, мы предлагаем прочитать вводную статью на официальном сайте: Что такое Apache Flink?
Архитектура маяка


По сути, Beacon читает события от Кафки . Все представлено в виде сообщения , от предупреждений до правил агрегирования, отложенных заказов и так далее. Трубопровод разделен на две ветви:

  • Тот, который выполняет агрегирование и запускает уведомления на основе правил клиента.
  • Тот, который обрабатывает шаги эскалации .

Тогда все объединяется , чтобы произвести  на  уведомление , что собирается быть вперед к нужному человеку. Уведомляющее сообщение помещается в Kafka, которое будет использоваться другим компонентом, называемым beacon-notifier.


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



Все объединяется в поток данных, разделяется (с ключом в Flink API) пользователями. Вот пример:

final DataStream<Tuple4<PlanIdentifier, Alert, Plan, Operation>> alertStream =

  // Partitioning Stream per AlertIdentifier
  cleanedAlertsStream.keyBy(0)
  // Applying a Map Operation which is setting since when an alert is triggered
  .map(new SetSinceOnSelector())
  .name("setting-since-on-selector").uid("setting-since-on-selector")

  // Partitioning again Stream per AlertIdentifier
  .keyBy(0)
  // Applying another Map Operation which is setting State and Trend
  .map(new SetStateAndTrend())
  .name("setting-state").uid("setting-state");



  • SetSinceOnSelector , который устанавливается с момента срабатывания предупреждения
  • SetStateAndTrend , который устанавливает состояние  (ПРОДОЛЖЕНИЕ, ВОССТАНОВЛЕНИЕ или ОК) и тренд (есть ли у нас более или менее метрики в ошибках).

Каждый из этого класса содержит менее 120 строк кода, потому что Flink справляется со всеми трудностями . Большая часть конвейера состоит только из классических преобразований, таких как Map, FlatMap, Reduce , включая их версии Rich и Keyed . У нас есть несколько функций процессов , которые очень удобны для разработки, например, таймера эскалации.


Интеграционные тесты

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

Запрашиваемое состояние

Убийственная особенность Apache Flink — это возможность запрашивать внутреннее состояниеоператора . Даже если это бета-функция, она позволяет нам узнать текущее состояние различных частей работы:
  • на каких этапах эскалации мы находимся
  • это он прилег или извед -ed
  • Какое оповещение продолжается
  • и так далее.



Благодаря этому мы легко разработали API для состояния запроса, который поддерживает наше представление предупреждений в Metrics Studio, наше кодовое имя для веб-интерфейса платформы данных метрик.
Развертывание Apache Flink

Мы развернули последнюю версию Flink ( 1.7.1 на момент написания) непосредственно на голых металлических серверах с выделенным кластером Zookeeper с использованием Ansible. Работа с Flink стала для нас действительно приятным сюрпризом, с понятной документацией и настройкой , а также впечатляющей устойчивостью . Мы можем перезагрузить весь кластер Flink, и задание перезапускается в его последнем сохраненном состоянии , как будто ничего не произошло.

Мы используем RockDB в качестве государственного сервера, поддерживаемого хранилищем OpenStack Swift,  предоставляемым OVH Public Cloud.

Для мониторинга мы полагаемся на Prometheus Exporter с Beamium, чтобы получить возможность наблюдать за состоянием здоровья рабочих.

Одним словом, мы любим Apache Flink!

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




Таким образом, мы настоятельно рекомендуем всем разработчикам взглянуть на Apache Flink. Я рекомендую вам пройти обучение Apache Flink , написанное Data Artisans. Более того, сообщество приложило немало усилий, чтобы легко развернуть Apache Flink в Kubernetes, поэтому вы можете легко попробовать Flink с помощью нашего управляемого Kubernetes!

Что дальше?

На следующей неделе мы вернемся к Kubernetes, поскольку мы расскажем, как мы работаем с ETCD в нашей службе OVH Managed Kubernetes .