Skip to main content
All quickstarts
ОбсервабилитиOSS

Предварительные требования

Что вы создадите

В OpenTelemetry каждый спан трассировки несёт набор атрибутов ресурса — метаданных в формате ключ-значение, описывающих сущность, которая создала телеметрию (имя сервиса, хост, регион облака, под Kubernetes и т. д.). Набор ключей различается в зависимости от сервиса и окружения, поэтому для таких данных естественно подходит тип Map в ClickHouse: ключи динамические и зависят от приложения, но в каждой строке их обычно лишь несколько. В этом кратком руководстве вы будете использовать clickhouse-local, чтобы загрузить реальные данные OTel-трассировки из CSV-файла в таблицу со столбцами Map(LowCardinality(String), String), а также научитесь выполнять запросы, фильтровать, агрегировать и оптимизировать данные в Map.
1

Скачайте пример данных

Набор данных содержит 6 120 спанов трассировки OTel, экспортированных из демонстрационного микросервисного приложения. Каждая строка включает столбцы ResourceAttributes и SpanAttributes с динамическими парами ключ-значение в формате JSON. Сохраните файл в каталог, путь к которому вам будет удобно использовать, например ~/data/data-otel-traces.csv.Скачать data-otel-traces.csv (2.9 MB)Вот как выглядит одна строка:
2

Создайте таблицу и загрузите данные

Запустите clickhouse-local и создайте следующую таблицу со схемой, соответствующей CSV. Ключевой столбец — ResourceAttributes Map(LowCardinality(String), String); LowCardinality используется для типа ключа, поскольку ключи атрибутов OTel берутся из относительно небольшого набора повторяющихся значений.
Теперь загрузите CSV с помощью движка таблицы file. Укажите путь к файлу, который вы сохранили:
Убедитесь, что данные загружены:
Вы должны увидеть 6 120 строк.
3

Запросите данные

Доступ к конкретному ключу — используйте синтаксис с квадратными скобками, чтобы получить значение из Map. Если в данной строке такого ключа нет, будет возвращено значение по умолчанию для типа значения (пустая строка для String):
Фильтрация по значению в map — найдите все спаны с определённым именем сервиса:
Проверьте, есть ли ключ — не каждый span содержит метаданные Kubernetes. Используйте mapContains, чтобы найти те, у которых они есть:
Проверьте все ключи, встречающиеся во всём наборе данных — это полезно, чтобы понять, что именно создаёт инструментирование:
Разверните Map в строки с помощью ARRAY JOIN — превратите каждую пару ключ-значение в отдельную строку — это удобно для составления перечней атрибутов или наполнения панелей мониторинга:
Фильтруйте maps с помощью mapFilter — извлекайте из каждого спана только атрибуты, связанные с Kubernetes:
Находите спаны с ошибками и их ресурсный контекст — сочетайте обычные фильтры по столбцам с доступом к Map:
4

Агрегирование по Map с помощью комбинатора -Map

Агрегатный комбинатор -Map в ClickHouse позволяет применять любую агрегатную функцию к столбцу типа Map, при этом она выполняется отдельно для каждого ключа. Результатом тоже будет Map — по одной записи на ключ с агрегированным значением. Это особенно полезно для метрик OTel, где значения Counter или Gauge хранятся в Map.Чтобы продемонстрировать это, создайте небольшую таблицу метрик, в которой каждая строка содержит количества HTTP-кодов состояния в виде Map(String, UInt64):
Теперь используйте sumMap, чтобы суммировать количество по каждому коду статуса для каждого сервиса:
Суффикс -Map работает с любой агрегатной функцией, поэтому вы можете так же легко использовать minMap, maxMap или avgMap:
Вы также можете комбинировать его с другими комбинаторами. Например, sumMapIf позволяет выполнять условную агрегацию — в данном случае суммируются только те минутные окна, в которых у сервиса уже были ошибки:
Почему это важно для OTel: Когда ваш OTel Collector записывает в ClickHouse поминутную разбивку по кодам статуса, sumMap позволяет агрегировать её в почасовые или суточные итоги одним запросом — без ARRAY JOIN, без разворота в строки и без необходимости заранее знать полный набор ключей. Любой ключ, встречающийся хотя бы в одной строке, автоматически включается в результат.
5

Оптимизируйте работу с часто используемыми в запросах ключами

Если вам постоянно приходится фильтровать данные по одному и тому же ключу в Map — часто это host.name — его можно вынести в материализованный столбец. Это позволит избежать линейного прохода по Map при каждом запросе:
Для существующих данных дозагрузите столбец:
Теперь WHERE HostName = 'prod-cart-01' считывает один выделенный столбец вместо всего map. Это рекомендуемый подход в схеме OTel ClickHouse для любых атрибутов, по которым вы часто выполняете запросы.

Ключевые выводы

  • Map(LowCardinality(String), String) — идиоматический тип для атрибутов OTel: он достаточно гибок, чтобы работать с меняющимися наборами ключей, а LowCardinality позволяет хранить ключи эффективно.
  • Синтаксис с квадратными скобками (map['key']) — самый распространённый способ доступа к значениям, но помните, что он выполняет линейный проход: для map с десятками ключей это нормально, а вот для сотен — уже не лучший вариант.
  • Материализованные столбцы — это выход из ситуации: когда ключ map становится частой целью фильтрации, вынесите его в отдельный столбец для индексированного, столбцового доступа.
  • mapContains, mapKeys, mapValues, mapFilter и ARRAY JOIN дают богатый набор инструментов для изучения и преобразования данных map, не выходя из SQL.
  • Агрегатный комбинатор -Map (sumMap, avgMap, maxMap и т. д.) агрегирует каждый ключ независимо по всем строкам — это идеально для свёртки счётчиков метрик OTel, когда набор ключей заранее неизвестен. Он также сочетается с другими комбинаторами (например, sumMapIf).

Что дальше

Далее ознакомьтесь со следующими руководствами по быстрому старту: Или перейдите к более подробной справочной документации:
ClickHouse Academy — Master ClickHouse with expert-designed training for every skill level

Check out the ClickHouse academy for on-demand and live training

Последнее изменение 28 августа 2026 г.