сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Мониторинг и логи

Метрики и Prometheus: типы и кардинальность

Метрики: модель сбора и типы

Поднял настоящий Prometheus - систему, которая собирает и хранит метрики, - и приложение, которое эти метрики отдаёт. Метрика тут это число, которое сервис регулярно сообщает о себе: сколько запросов обработал, сколько ошибок, сколько занято памяти. Одна нормальная метрика «сколько запросов» с меткой статуса (метка - это приписанная к метрике пара «имя и значение») дала 2 ряда данных. Вторая, где я по глупости положил в метку идентификатор пользователя, - 500 рядов. Всего в базе стало 1107 рядов, и сам Prometheus занял 79 мегабайт памяти. Пятьсот пользователей - это ещё маленький сервис.

Стержень: метрики собираются опросом, а стоимость хранения определяется не числом метрик, а числом сочетаний меток.

// Формулировки: «почему Prometheus сам ходит за метриками?», «чем счётчик отличается от измерителя?», «что такое кардинальность и чем она опасна?»

Кто к кому ходит

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

Проверил, что бывает при падении цели. Пока приложение живо, up равна 1. Я остановил контейнер - через несколько секунд up стала 0, и это готовый сигнал «сервис недоступен», который не надо специально придумывать. А вот сами метрики приложения из запросов ПРОПАЛИ: не замерли на последнем значении, а именно перестали возвращаться. Это важно: график не «застывает», он обрывается.

// Обратная сторона модели опроса - недолговечные задачи. Скрипт, который живёт 200 миллисекунд, опросить невозможно: к моменту прихода Prometheus его уже нет. Для таких случаев ставят промежуточный приёмник, куда задача сама отправляет результат перед смертью, а Prometheus опрашивает уже его.

модель опроса
сборщик сам ходит за метриками по расписанию
метрика up
1, если опрос цели удался; готовый сигнал недоступности
промежуточный приёмник
место, куда короткоживущие задачи кладут метрики перед смертью

Счётчик, измеритель и гистограмма

Счётчик только растёт. У меня «всего запросов» показал 21 564 успешных и 899 ошибок. Само по себе это число бесполезно: оно накопилось с момента запуска. Смысл появляется от скорости роста - я посчитал её и получил 345,5 запроса в секунду и 14,5 ошибки в секунду.

Измеритель может расти и падать: это мгновенное значение вроде «запросов прямо сейчас в обработке» (у меня 10) или «свободно памяти». Его читают как есть, скорость роста для него бессмысленна.

// Гистограмма - счётчики попаданий в корзины по длительности. У меня стояли корзины 0,005, 0,01, 0,025, 0,05, 0,1, 0,25, 0,5, 1, 2,5 и 5 секунд плюс «всё остальное». Из неё считаются квантили - значения, ниже которых лежит заданная доля запросов, - но считаются по корзинам, а не по точным значениям, и это накладывает ограничения, о которых отдельно.

// И ещё один важный факт про счётчики, который я проверил специально. Приложение перезапустилось - счётчик начался с нуля (у меня 3821 вместо 21 564). Сырое значение при этом «упало», а вот скорость роста осталась правильной, 316 в секунду: функция расчёта скорости умеет замечать сброс счётчика и не считает его отрицательным всплеском.

счётчик
только растёт; смысл имеет его скорость роста, а не само значение
измеритель
мгновенное значение, может расти и падать
гистограмма
счётчики попаданий в корзины; из неё считают квантили

Кардинальность: чем платят за красивые метки

Ряд данных в Prometheus - это уникальное сочетание имени метрики и всех её меток. Метрика с меткой статуса на два значения даёт 2 ряда. Та же метрика с меткой идентификатора пользователя даёт столько рядов, сколько было пользователей: в моём замере 500 при пятистах пользователях, ровно один к одному.

Дальше умножение. Добавили метку с адресом клиента - плюс тысячи. Добавили путь запроса, а в нём номер заказа - плюс миллионы. Каждый ряд занимает память в текущем срезе и место на диске, а запросы по ним замедляются. У меня 1107 рядов держали 79 мегабайт, и это игрушечный стенд.

// Правило простое: в метках живут ЗАКРЫТЫЕ множества. Статус, метод, код ответа, имя сервиса, зона - у них конечное и небольшое число значений. Идентификаторы пользователей, заказов, сессий, полные пути с числами - в метки не кладут никогда. Если такая детализация нужна, для неё есть логи и трассировки, где стоимость устроена иначе.

ряд данных
уникальное сочетание имени метрики и всех её меток
кардинальность
число таких сочетаний; растёт умножением значений меток

Как отвечать: «Что такое кардинальность метрик и чем она опасна?»

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

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

На чём валятся

  • Кладут в метки идентификаторы пользователей и заказов и взрывают хранилище.
  • Читают сырое значение счётчика вместо его скорости роста.
  • Ждут, что метрики упавшего сервиса «замрут» на последнем значении. Они пропадают.
  • Пытаются опрашивать короткоживущие задачи вместо промежуточного приёмника.
  • Считают, что счётчик после перезапуска сломает график. Расчёт скорости умеет замечать сброс.

Проверьте себя

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

  1. #dvo_metrics1 / 5
    В метрику запросов добавили лейбл с идентификатором пользователя. Через сутки Prometheus упал по памяти. Почему?
    A)Лейблы со строками не поддерживаются и ломают формат хранения
    B)Каждое значение лейбла порождает отдельный временной ряд
    C)Скрейп стал медленнее и очередь запросов переполнила память
    D)Идентификаторы попали в индекс логов и раздули хранилище
    показать ответ и разбор
    +B)Каждое значение лейбла порождает отдельный временной ряд

    // разбор: Временной ряд определяется именем метрики и полным набором пар лейблов. Идентификатор пользователя даёт столько рядов, сколько пользователей: сотни тысяч серий, каждая со своим индексом и буферами в памяти. Отсюда правило: в лейблы кладут только значения с малым и предсказуемым числом вариантов — сервис, метод, код ответа. Всё уникальное (идентификаторы, урлы с параметрами, трейсы) живёт в логах и трассах.

  2. #dvo_metrics2 / 5
    Нужно снимать метрики хоста (CPU, диск, память), но сам сервис их не отдаёт. Как получить их в Prometheus?
    A)Prometheus сам собирает системные метрики хоста
    B)Поставить экспортёр (node_exporter), Prometheus скрейпит его
    C)Слать метрики хоста в Prometheus по syslog
    D)Читать /proc напрямую из правил Prometheus
    показать ответ и разбор
    +B)Поставить экспортёр (node_exporter), Prometheus скрейпит его

    // разбор: Prometheus работает по pull: скрейпит HTTP-эндпоинт /metrics. Если источник сам метрики не отдаёт (ОС, БД, железо), ставят экспортёр — отдельный процесс, который снимает показатели и публикует их в формате Prometheus (node_exporter для хоста, postgres_exporter и т.д.). Prometheus скрейпит экспортёр как обычную цель. Своего сбора из /proc или приёма по syslog у него нет.

  3. #dvo_metrics3 / 5
    Для задержки ответа выбирают между summary и histogram. Почему для агрегируемых по кластеру квантилей берут histogram?
    A)Histogram копит бакеты и агрегируется
    B)Summary точнее, но занимает больше места на диске
    C)Histogram отдаёт готовый квантиль без вычислений
    D)Summary для измерения задержки не годится
    показать ответ и разбор
    +A)Histogram копит бакеты и агрегируется

    // разбор: summary вычисляет квантили на стороне клиента, для каждого инстанса свои — а такие готовые квантили нельзя корректно усреднять/суммировать по кластеру. histogram копит наблюдения по бакетам (счётчики), которые складываются между инстансами, и итоговый квантиль считают из суммарных бакетов через histogram_quantile. Поэтому для общекластерных p95/p99 берут histogram; summary — когда квантиль нужен локально и агрегация не важна.

  4. #dvo_metrics4 / 5
    Короткая batch-джоба выполняется секунды и завершается. Prometheus не успевает её заскрейпить. Как снять её метрики?
    A)Уменьшить scrape_interval до долей секунды
    B)Джоба должна сама слать метрики прямо в TSDB Prometheus
    C)Держать джобу живой ещё минуту после завершения
    D)Через Pushgateway: джоба пушит метрики, Prometheus скрейпит шлюз
    показать ответ и разбор
    +D)Через Pushgateway: джоба пушит метрики, Prometheus скрейпит шлюз

    // разбор: Pull-модель не годится для короткоживущих задач: процесс исчезает раньше, чем Prometheus придёт скрейпить. Для них Pushgateway: джоба по завершении пушит свои метрики в шлюз, а Prometheus скрейпит уже шлюз. Осторожно: Pushgateway хранит последнее пушнутое значение (метрики не «тают» сами — нужна очистка), и это не способ превратить Prometheus в push-систему для обычных сервисов.

  5. #dvo_metrics5 / 5
    Что такое метрика в мониторинге?
    A)Числовое измерение во времени
    B)Текстовая запись о событии в приложении
    C)Порог, при достижении которого шлют оповещение
    D)Отчёт о работе сервиса за прошедший месяц
    показать ответ и разбор
    +A)Числовое измерение во времени

    // разбор: Метрика это ряд чисел с отметками времени: число запросов, занятая память, длина очереди. Числа дёшево хранить и агрегировать — потому по метрикам строят графики и алерты, а подробности ищут уже в логах.

дальше

Теорию прочитали. Навык ставится повторением

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