Cardinality меток
Тема дорожной карты · Loki
Кардинальность в Grafana Loki — это общее количество уникальных комбинаций значений меток, существующих среди всех потоков логов, и высокая кардинальность является одной из наиболее распространённых проблем производительности в Loki. Когда вы добавляете метку с высокой кардинальностью — например, user_id, request_id или IP-адрес — Loki создаёт новый поток для каждого уникального значения, что приводит к хранению тысяч открытых чанков в памяти Ingester и к стремительному росту индекса. Grafana Loki специально спроектирован для наборов меток с низкой кардинальностью: рекомендуется поддерживать не более нескольких тысяч уникальных потоков на тенант, а значения с высокой кардинальностью лучше помещать в тело лог-строки, откуда их можно извлечь во время запроса с помощью операторов извлечения меток LogQL. Отслеживать кардинальность можно через logcli или конечную точку метрик Loki /metrics, в частности с помощью счётчика loki_ingester_streams_created_total. Распространённый паттерн рефакторинга — заменить метку с высокой кардинальностью одной меткой с низкой кардинальностью вроде {job="nginx"}, а затем фильтровать по извлечённому значению с помощью выражения | json user_id="user_id" в LogQL.
Как это работает
Cardinality меток: в Loki log stream — уникальная комбинация labels. Labels — key-value pairs (e.g., {app="nginx", env="prod", pod="nginx-7d"}), идентифицирующие источник. Loki индексирует labels, НЕ содержимое лога — поэтому design labels тщательно критичен. High-cardinality labels (user_id, request_id, timestamp) взрывают индекс + убивают perf. Структурированные логи (JSON) намного легче фильтровать + extract из них чем free text — логируйте в JSON.
Когда применять
Держите labels мало + low-cardinality — app, env, namespace, level хороши; user_id, trace_id, timestamp плохи (high cardinality). Используйте содержимое лога (не labels) для filter по request-specific значениям через LogQL |= или |~. Всегда structured-log (JSON) — Promtail/Loki парсят поля без дорогого regex.
Типичные ошибки
Ловушки Cardinality меток: добавляют request_id или user_id как label (cardinality explosion → Loki умирает); слишком мало labels (один огромный stream, не масштабируется ingest); inconsistent labels между сервисами (queries становятся per-service спагетти); unstructured logs, требующие regex на каждом query.