Кардинальность лейблов
Урок про главную ловушку Prometheus — взрыв кардинальности лейблов.
Кардинальность метрики — это число уникальных временных рядов, которое она порождает; оно равно произведению количеств уникальных значений всех её лейблов.
Это причина номер один, по которой Prometheus съедает память и тормозит. Один неосторожный лейбл способен превратить одну метрику в миллионы рядов. Разберём, как этого избежать.
Как считается кардинальность
Каждая уникальная комбинация значений лейблов — отдельный ряд. Перемножьте количества значений каждого лейбла, и получите число рядов.
http_requests_total{method, status, instance}
method: 5 значений
status: 8 значений
instance: 10 значений
итого: 5 * 8 * 10 = 400 рядов (нормально)А теперь добавим лейбл user_id с миллионом значений:
+ user_id: 1 000 000 значений
итого: 400 * 1 000 000 = 400 000 000 рядов (катастрофа)Что нельзя класть в лейблы
- ID пользователей, сессий, заказов.
- Email, IP-адреса.
- URL с встроенными параметрами (
/user/123/order/456). - Timestamp и любые непрерывно растущие значения.
Такие данные — для логов и трейсов, не для лейблов метрик.
Как считать кардинальность вручную
labels = {
"method": 5,
"status": 8,
"instance": 10,
"endpoint": 20,
}
series = 1
for name, count in labels.items():
series *= count
print("Лейблы и их мощности:", labels)
print("Всего временных рядов:", series)Вывод:
Лейблы и их мощности: {'method': 5, 'status': 8, 'instance': 10, 'endpoint': 20}
Всего временных рядов: 8000Как работает под капотом
Prometheus держит индекс всех серий в памяти. Каждый ряд — это запись в индексе плюс буфер свежих сэмплов. Поэтому стоимость определяется не объёмом значений во времени, а именно числом уникальных рядов. Миллионы рядов — это гигабайты RAM и медленные запросы, даже если каждый ряд хранит всего пару точек. Нормализуйте лейблы заранее: вместо сырого URL кладите шаблон маршрута (/user/:id/order/:id).
Частые ошибки
- Сырой URL в лейбле. Каждый уникальный путь — новый ряд; кладите шаблон маршрута.
- Динамические лейблы из пользовательского ввода. Атакующий может намеренно раздуть кардинальность.
- Не следить за ростом рядов. Отслеживайте
prometheus_tsdb_head_seriesи алертьте на резкий рост.
Итог
- Кардинальность = произведение мощностей всех лейблов.
- ID, email, URL с параметрами в лейблах метрик запрещены.
- Нормализуйте значения лейблов и следите за числом рядов.