Добрый день, дорогой читатель! Данная статья возникла в результате попытки взглянуть на оперативный мониторинг с аналитической точки зрения.
Вам будет полезно, если:
- что-то из следующего списка знакомо: Grafana, InfluxDB, Prometheus, Zabbix или другая система мониторинга со схожими идеями;
- вы не являетесь экспертом/профессионалом/уверенным посредником в различных видах отображения временных рядов и математической статистике (иначе вам, скорее всего, будет скучно);
- есть желание посмотреть на некоторые аспекты «под микроскопом».
- Скажите, пожалуйста, куда мне отсюда идти? -Куда ты хочешь пойти? - ответил Кот. «Мне все равно…» — сказала Алиса.Путешествие начинается.«Тогда не имеет значения, куда ты пойдешь», — сказал Кот. «… просто чтобы куда-то попасть», — объяснила Алиса.
«Ты обязательно где-нибудь окажешься», — сказал Кот. «Тебе просто нужно идти достаточно долго».
«Алиса в стране чудес» Льюис Кэрролл
Когда дело доходит до поиска проблем в реальных условиях, существует множество предубеждений и ошибок.
Во многом потому, что в постмортемах в основном пишут о том, как избежать подобных проблем в будущем, а не о том, почему не удалось починить сервис быстрее.
Когда вы видите проблемы достаточно часто, вопрос «почемуЭ» появляется сам по себе в голове.
Почему? Были собраны все метрики, заранее сделаны дашборды по всем критичным компонентам и даже подготовлено пару триггеров (возможно, они даже сработали)! Здесь начинается поиск подводных камней, и здесь начинается моя история.
Фундаментальные проблемы
Итак, в начале было слово было RFC1065 :… 3.2.3.3. Прилавок Этот общеприкладной тип представляет собой неотрицательное целое число, которое Роуз и МакКлогри [страница 8] RFC 1065 SMI, август 1988 г.Исходя из этого достоверно известно, что в августе 1988 года уже существовала спецификация весьма недвусмысленная.монотонно возрастает, пока не достигнет максимального значения, когда разворачивается и снова начинает увеличиваться с нуля.
Эта памятка задает максимальное значение 2^32-1 (4294967295 десятичное) для счетчики.
3.2.3.4. Измерять Этот общеприкладной тип представляет собой неотрицательное целое число, которое может увеличиваться или уменьшаться, но фиксируется на максимальном значении.
Этот memo указывает максимальное значение 2^32-1 (4294967295 десятичное) для манометры.
…
разделены две сущности: накопительный счетчик и измерение .
Но каким-то образом мы продолжаем страдать от незнания этой разницы и по сей день, даже несмотря на попытки встроить эту разницу в современные системы самым очевидным образом, например.
Прометей .
Это была фундаментальная проблема номер один.
Проблема номер два — необъяснимая всепоглощающая любовь к среднему арифметическому: независимо от происхождения, значения и поведения метрики, многие люди выбирают ее, когда им нужно использовать функцию агрегирования.
И тут мы наступаем на детские грабли из математической статистики – нельзя просто взять среднее значение чего-либо за неопределенный интервал и ничего не потерять.
Но интервал действительно может быть не очень конкретным.
Если в качестве UI для просмотра метрик взять Grafana, которая, ИМХО, является стандартом де-факто в отрасли, то по умолчанию у нас стоит $__interval, который, согласно документации, примерно рассчитывается исходя из разрешения экрана.
А это уже неопределенность - за исключением того, что внутри организации категорически запрещено использовать любые экраны с разрешением, отличным от 4к.
Не забывайте про мобильные устройства, Макбуки, телевизоры с дашбордами — и тут боль фронтенд-разработчиков становится яснее.
Хотя, конечно, без этой ссылки ситуация могла бы стать гораздо хуже.
Кроме того, нас (как опытных пользователей) может не устроить вариант по умолчанию по многим причинам.
Возьмем эту конструкцию в качестве примера:
Ээмпирически проверено, что значения «Количество шагов» 200 и 300 работают хорошо (остальное, думаю, не нуждается в пояснениях.
И попробуем изменить глубину запроса: если интервал получения метрик 10 секунд , мы получим следующую таблицу:
Глубина запроса | Размер выборки $group_time | Количество баллов для расчета среднего | |
---|---|---|---|
Пример InfluxQL | ГДЕ время> сейчас()-.
|
ГРУППИРОВАТЬ ПО времени(.
) |
|
1 час | 20 лет | 2 | |
1 день (24 часа) | 5 м | 30 | |
1 Вт | 1 час | 360 | |
1 месяц | 3 часа | 1080 |
Среднее из среднего
Пришло время вернуться к началу истории и вспомнить о накопительных счетчиках.
На эту тему я нарисовал следующую картинку (опять же с примерами из Influx, но и в некоторых других системах мы можем наблюдать аналогичные проблемы):
Существует некоторая путаница относительно именования функций в InfluxDB: Эта статья вы можете понять, что: Мгновенная скорость изменения эквивалентна производной, известной из школьного курса математики.
А в случае дискретных точек, полученных просто путем периодических измерений, мы, соответственно, имеем дело со средней скоростью изменения.
Но это не проблема.
Проблема в том, что когда мы используем здесь среднее значение, мы не получаем того, чего хотим.
Если счетчик растет нелинейно, мы получим сдвиг «середины» внутри выборки данных, то есть результат просто не покажет изменение значения за заданный интервал.
Ну и в итоге такая конструкция алгоритмически выглядит совершенно глупо, несмотря на отсутствие явных просадок в производительности, ведь измеряя разницу между двумя точками накопительного счетчика, мы уже получаем средний скорость изменения.
Конец или начало
Но на этом «странности» не заканчиваются: внимательный пользователь заметит некоторое искажение последнего значения вниз, если использовать последнее, как говорилось выше (на примере InfluxQL, в promql другая история ).При использовании последнего в запросе последний сегмент не будет равен выбранному интервалу группировки.
В этом случае база данных принимает момент времени в качестве начала каждого интервала, всегда округляемый в меньшую сторону.
Например, в случае группировки по часам мы будем наблюдать изменение значения счетчика на последнем интервале за час, начиная с 00 минут этого часа.
Поэтому на данный момент я остановился на варианте non_negative_derivative(first(.
)) для большинства случаев.
Альтернатива, не имеющая этой проблемы — разделение данных на части, начиная с настоящего момента, — тоже не очень хороша: каждое обновление графика (а значит, и обновление опорной точки) будет требовать перерасчета всех значений.
Простые функции, отличные от средних
Почувствуй, что мы приближаемся к сути происходящего безумия ? Давайте разберем каждый шаг.Ну, нас не устроило среднее, у InfluxDB есть масса других замечательных функций: max, min, last и кое-что, возможно, не столь очевидное — stddev. В прометее есть аналогичные min_over_time, max_over_time, stddev_over_time, но дальше я разберу это на примере в Influx (есть предположение, что между ними много общего в этой части).
Последнее, думаю, не нуждается в пояснениях, но если выбросы важны, то оно получается даже лучше среднего: с ним есть хоть какой-то шанс заметить выбросы на графиках, тогда как среднее усредняет все, как мы «хотели».
"" Очевидно, что max и min будут прекрасно работать независимо друг от друга.
Но что, если объединить эти два значения и добавить к ним среднее значение? Оказывается, эта идея не только не нова, она на самом деле стара, как пирамиды.
Из «классических» примеров в системах мониторинга мне запомнились тенденции в Zabbix (Я специально искал ссылку на более старую версию) и Графитовый шепот , как и ранее RRDtool , который также использовался в Кактусы , где по умолчанию по какой-то причине отсутствовал min. Возможно, несмотря на весь последующий текст, это один из лучших подходов.
Он достаточно информативен, не слишком шумен, интуитивно понятен, дешев в реализации, относительно универсален и доступен практически во всех современных системах.
Примеры такого рендеринга:
- в Заббиксе
- в Графане
«Математический» подход к рисованию Это все хорошо, но не предел мечтаний хотя бы потому, что есть stddev - то есть стандартное отклонение, или по русски среднеквадратичное отклонение .
Кратко отмечу, что таким образом мы получаем возможность наглядно наблюдать колебания нашей метрики, особенно когда они становятся больше обычного.
Плюс, что еще более важно, вы можете оценить «близость» точек выборки к среднему значению.
Однако в этом случае мы теряем представление об абсолютных значениях исходного значения, чего нам не хотелось бы (если, конечно, мы изначально представляли, что означают эти абсолютные значения, что не всегда верно ).
Итак, мы получили это самое отклонение и хотим показать его на графике вместе с исходными данными: это можно сделать с помощью полоса ошибок .
Есть еще более интересный вариант — « коробка для усов », который построен на базе 1-го, 2-го и 3-го квартиль (25% процентиль, медиана и 75% процентиль).
Что нам нужно для лучшей жизни? Нет :) Хотя бы потому, что не первый , не второй не нашлось во всеми любимом Графане.
Правда, меня это не сильно смутило и я поигрался с данными, используя pandas и seaborn (причём даже сюжетно).
Однако это не сильно приблизило меня к цели, поскольку «коробка с усами» имеет очевидные недостатки, унаследованные от тех величин, которые в ней содержатся.
Самый быстрый способ понять суть проблемы — использовать ключевые слова «анимация Дюжины Датазавра» в Google.
На гифке показано, что многие точки можно расположить огромным количеством способов без существенного изменения среднего значения, стандартного отклонения и Коэффициент корреляции Пирсона .
В случае с временными рядами, конечно, нельзя получить такое же богатство вариантов из одного ряда данных через фиксированный интервал сбора показателей, но тем не менее оно есть.
Допустим, идея «коробочки с усами» оправдалась.
Что дальше? Давайте рассмотрим варианты визуализации в seaborn! Берем первое попавшееся: скрипичный сюжет. Классная штука, фразы «оценка плотности ядра» и «метод окна Парцена-Розенблатта» звучат хорошо и могут привести нас к какой-то цели, но на этот раз придется пройти мимо: скрипичный сюжет не поддерживается в Grafana.
Классификация
Пришло время остановиться на секунду и задуматься: в чем проблема, которую мы потенциально хотим обнаружить, изучая граф? Что нормально, а что нет? Как определить аномалию? Почему мы не видим аномалию, когда она действительно существует? Было бы неплохо иметь хоть какую-то классификацию.Помимо того, что мы уже знаем разницу между накопительным счетчиком и измерением, мы можем найти массу информации о классификации метрик.
Возьмем, к примеру, один очень авторитетный источник: книгу Google SRE. Там мы найдём упоминание о «четырёх золотых сигналах» (думаю, читателю лучше обратиться к первоисточнику, и я просто упомяну их названия): латентность, трафик, ошибки, насыщенность.
В идеальном мире все метрики в системе помечены этими терминами, либо можно как-то понять (по длинному понятному человеку названию), к чему относится эта метрика в выбранной классификации.
За примером далеко ходить не надо: если у нас есть метрика насыщенности и мы не переборщили и измерили ее как % от 100, то можно понять следующее: когда она принимает значение 100, система скорее всего «перенасыщен» запросами, а когда он равен 0, наоборот, и это, скорее всего, тоже не очень хорошо.
Также в большинстве случаев ошибки имеют накопительный счетчик, что позволяет легко интерпретировать происходящее.
Скорость и производительность
Вернемся к теме отображения метрик и столкнемся с еще одной проблемой: медленные или нефункциональные информационные панели .Чтобы понять, почему это может произойти, давайте посмотрим на происхождение метрик, то есть на их сбор агентами/сборщиками.
Здесь мы видим две модели (которые, собственно, мы видим практически во всех современных информационных системах): тяни и толкай.
В этом месте идут многовековые священные войны между приверженцами двух противоборствующих лагерей, и я стараюсь сохранять нейтралитет, чтобы не быть сожженным на костре за невежество.
Поэтому лишь упомяну, что, на мой взгляд, наиболее ярким представителем лагеря выталкивания являются римановы-инструменты, а лагеря вытягивания – всем известный Прометей.
Несколько промежуточную стратегию использует Telegraf, который имеет как входные плагины для метрик для обеих моделей, так и выходные плагины для обеих моделей.
К сожалению, категории плагинов Discovery нет; вместо этого внутри input-плагинов есть решения, разнородные по конфигурации и коду.
Здесь каждый ветеран индустрии мониторинга заметит, что обнаружение ресурсов на уровне сбора данных существует уже давно, возьмем тот же LLD (низкоуровневое обнаружение) в Zabbix, но переиспользовать опыт повторного использования опять же не удалось.
предыдущие итерации.
Однако это не все «улучшения»: механизм доставки конфигурации также деградировал с точки зрения удобства использования (имеется в виду на нижнем уровне).
Вместо этого предлагается перенести эту проблему на уровень управления конфигурацией внутри системы доставки (например, prometheus-operator), что логично, но не всегда хорошо реализуется на практике.
Более того, несмотря на то, что всех отправляли напрямую в.
Kubernetes с запросами на динамическую настройку, не все готовы это принять - взять для примера недавняя статья в блоге Influxdata .
Более-менее продуманный альтернативный подход (конфигурация через API/RPC) был найден в щелчок , которые, в свою очередь, имели и другие недостатки (но о покойном либо отзываются хорошо, либо не отзываются вообще).
Допустим, у нас есть модель извлечения для сбора метрик и какой-то агент сбора данных, у которого есть параметр интервала сбора.
Этот параметр может быть как глобальным, так и настраиваемым для каждой конкретной серии измерений.
Чем короче интервал, тем больше вероятность, что мы загрузим базу.
А может и нет. Может быть, у нас вообще нет базы: мы получаем оповещения на основе метрик во время выполнения (например, уже упомянутый Риман позволяет легко реализовать подобную схему).
Но в более классической схеме мы все равно будем ждать базу после некоторого кэша данных.
Кэш, в свою очередь, находится либо после их сбора, либо в самом процессе-сборщике, либо внешнем (например, какой-нибудь очереди).
Если мы возьмем, к примеру, чуть более старые стеки, использующие Graphite и/или statsd, мы увидим агрегатор посередине, который предназначен не только для снижения нагрузки на базу данных, но и для ускорения рендеринга пользовательского интерфейса.
За это отвечает Прометей.
правила записи И Танос Компакт , И в ГАЛОЧКА -stack есть выбор между двумя, ИМХО, весьма сомнительными вариантами: Продолжает запросы в InfluxDB и ТИКскрипт в Капаситоре.
При этом мы можем иметь дело с данными, которые изначально были агрегированы на стороне коллектора, например, Histogram и Summary в Prometheus, а подобные структуры можно найти в Интерфейс аккумулятора в Телеграфе.
В конечном итоге, весьма абстрактно, получается, что прежде чем появиться на экране, метрика проходит примерно такой путь:
Отсюда мы видим, что чем больше точек мы пытаемся отобразить в пользовательском интерфейсе, тем больше данных нам придется перенести с одного этапа на другой.
И здесь есть загвоздка: даже если мы изначально используем относительно низкоуровневый инструмент для рендеринга данных, в большинстве случаев мы хотим, чтобы все данные были непосредственно в браузере клиента или, в крайнем случае, на этапе предварительной обработки UI. Но зачастую объем данных таков, что извлечение необработанных данных непосредственно из базы данных уже создает проблемы.
Также не стоит забывать, что обратный поток из базы данных может «накрыть» UI-препроцессинг или сам UI, либо последний в результате троттлинга отбросит часть или все данные, поступающие из базы данных.
В этом случае, как правило, необходима агрегация данных на уровне базы данных или отдельным сервисом до/после базы данных.
В этот момент уместно вернуться к «ящику с усами» и понять, что для его рисования без выбросов достаточно 3-х значений на выборку данных, что представляет этот метод в очень выгодном свете, если стоит задача минимизировать количество сохраняемых метрик.
Поэтому хоронить его, похоже, еще рано.
гистограмма
Если вернуться к еще недосказанным оставшимся вариантам рендеринга, то обнаружим, что надежда еще есть: гистограммы упоминаются в «Прометее», «Телеграфе» и многих других системах мониторинга.Ограниченное распространение гистограмм кажется парадоксальным, учитывая, что тепловая карта (в данном случае не что иное, как гистограмма во времени) — это встроенный функционал Grafana. Естественно, гистограмма как таковая тоже присутствует в «стандартной поставке», и ее тоже можно использовать.
Картина из официальной документации Grafana
Кроме того, в Grafana можно создать тепловую карту в формате сегментов временных рядов, что позволяет визуально группировать метрики по тегам, например, показывать загрузку ЦП по ядрам:
Общий Обобщая вышесказанное, получаем следующую логику действий по отрисовке дашборда:
- Классифицируем показатели:
накопительный счетчик или мгновенное измерение;
задержка, трафик, ошибки или насыщение.
- Если это накопительный счетчик, то помимо использования функции для расчета курса мы знакомимся с особенностями его работы в конкретной системе.
- Если есть необходимость заглянуть достаточно далеко в прошлое (что почти всегда верно), мы думаем, какие функции агрегации нужны и на каком этапе передачи данных эти функции следует применить, чтобы ничего не тормозило.
- Мы стараемся сделать все максимально простым.
Если это невозможно и в Grafana (или родном UI системы мониторинга) чего-то явно не хватает, то, скорее всего, не тратя слишком много времени, можно сделать что-то свое на Python или JS.
Но это не повод грустить — графики могут быть не только полезными, но и забавными: например, это цифры , похожие на елочные игрушки.
Послесловие Для тех, кто хочет больше информации, я рекомендую статья с похожей линией рассуждений, классной анимацией и другим выводом.
Также не будет лишним упомянуть недавний пост Александра Валялкина о гистограммах.
И интересно видео о задержке и процентилях .
Теги: #Системное администрирование #Администрирование серверов #Визуализация данных #Статистика в ИТ #Grafana #influxdb
-
Css — Мой Лсд
19 Oct, 24