awesome-everything EN
↑ Обратно к восхождению

Наблюдаемость

Метрики и cardinality: cost-модель time-series database

Суть Как работают метрики в модели Prometheus, почему cardinality — главный драйвер стоимости, и что происходит при добавлении одного неограниченного label.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Команда добавляет label customer_email к counter request_total, чтобы отслеживать частоту ошибок по клиентам. Через два часа Prometheus исчерпывает память, и 15 минут алертов теряются. Label выглядел безобидно.

Как хранится метрика

Каноническая модель — Prometheus. Метрика идентифицируется парой (metric_name, label_set), где label_set — небольшой фиксированный набор пар key=value. Каждая уникальная комбинация значений label создаёт одну time series — поток сэмплов (timestamp, value), обычно собираемых каждые 15 с.

Четыре стандартных типа метрик:

  • Counter — монотонно возрастающее целое. Осмысленна только скорость изменения (в секунду). Пример: http_requests_total.
  • Gauge — мгновенное значение, может расти и падать. Пример: memory_used_bytes, queue_depth.
  • Histogram — распределяет наблюдения по предопределённым bucket’ам для percentile-запросов. Пример: http_request_duration_seconds с bucket’ами [0.01, 0.05, 0.1, 0.5, 1.0, 5.0].
  • Summary — предвычисленный перцентиль на реплике. Редко используется для новой инструментации: нельзя агрегировать между репликами.
ТипРастёт/падаетИспользовать дляПример
CounterТолько вверхСкорость событийhttp_requests_total
GaugeОбаТекущее состояниеmemory_used_bytes
HistogramТолько вверх (bucket’ы)Распределение latency, перцентилиhttp_request_duration_seconds
SummaryПредвычисленПерцентиль на источнике (не агрегируем)Устарел; предпочтительнее histogram

Cardinality: главный драйвер стоимости

Каждая уникальная комбинация значений label создаёт отдельную time series в TSDB. Математика мультипликативная:

  • route (20 шаблонов) × method (5 методов) × status_class (4 класса) = 400 series — нормально.
  • Та же метрика + user_id (100 к активных пользователей) = 100к × 20 × 5 × 4 = 40 миллионов series — Prometheus падает с OOM на 16 ГБ.

Prometheus хранит около 3 КБ на активную series в head block. При 40 М series — 120 ГБ, что далеко за пределами памяти любого рядового сервера.

Правило: label ставь только на значения из небольшого фиксированного набора — шаблоны маршрутов, а не полные URL; классы статусов, а не коды статусов; сегменты клиентов, а не ID клиентов. Всё с неограниченными значениями — в логи (cardinality бесплатна) или в трейсы (сэмплированы), не в метрики.

Exemplar: мост метрика → трейс

Когда histogram записывает медленное наблюдение, клиент может прикрепить один exemplartrace_id запроса, создавшего это наблюдение. Grafana отображает exemplar’ы как точки на тепловой карте histogram; клик по точке открывает соответствующий трейс.

Exemplar’ы (стандартизированы в Prometheus 2.32, начало 2022) устраняют разрыв: «метрики говорят, что что-то медленно, но нет конкретного запроса для дальнейшего анализа.» Они позволяют не добавлять user_id в label метрик — cardinality остаётся управляемой — и при этом навигировать от агрегированного всплеска к одному конкретному запросу через трейс.

Числа Prometheus: cardinality и стоимость
Байт на активную series в head block Prometheus
~3 КБ
Безопасная зона series на 16 ГБ
~5 М
Множитель cardinality на один high-card label
100× — 10 000×
Типичный интервал scrape
15 с
Series от route × method × status_class (20×5×4)
400
Дополнительных series при добавлении user_id (100 к)
40 М
Викторина

Команда добавляет customer_email к counter request_total. Prometheus исчерпывает память за несколько часов. Почему?

Викторина

Что делает exemplar на метрике histogram?

Викторина

Какой тип метрики использовать для 'длительности запроса checkout, чтобы можно было запросить p99 по всем репликам'?

Вспомните перед уходом
  1. 01
    Объясни своими словами, почему метрики дёшевы для запроса, но слепы, а логи мощны, но дороги.
  2. 02
    Метрика имеет label'ы: route (30 шаблонов), method (5), status_class (4), region (3). Безопасно ли это? Что сделает её опасной?
  3. 03
    Почему использовать exemplar вместо добавления user_id как label метрики?
Итог

Метрика Prometheus идентифицируется парой (имя, label_set); каждая уникальная комбинация значений label создаёт одну time series, хранящуюся примерно в 3 КБ в head block. Предагрегация при записи делает запросы быстрыми за годы, но означает, что метрики могут отвечать только на вопросы об измерениях, помеченных заранее. Cardinality — произведение числа значений всех label — главный драйвер стоимости: один неограниченный label вроде customer_email на загруженной метрике может умножить число series с тысяч до десятков миллионов, вызвав OOM сервера. Четыре типа метрик: counter (скорость изменения), gauge (мгновенное), histogram (percentile-запрашиваемое распределение), summary (предвычисленное, не агрегируемое). Exemplar’ы соединяют агрегированную метрику с конкретным трейсом, устраняя необходимость в high-cardinality идентификаторах как label.

Связанные уроки
встречается в167
Продолжить восхождение ↑Логи и объём: cost-модель структурного логирования
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.