ОбсервабилитиOSS
Предварительные требования
- На вашем компьютере должен быть установлен clickhouse-local. Чтобы начать работу, см. руководство по настройке clickhouse-local.
Что вы создадите
Map в ClickHouse: ключи динамические и зависят от приложения, но в каждой строке их обычно лишь несколько.
В этом кратком руководстве вы будете использовать clickhouse-local, чтобы загрузить реальные данные OTel-трассировки из CSV-файла в таблицу со столбцами Map(LowCardinality(String), String), а также научитесь выполнять запросы, фильтровать, агрегировать и оптимизировать данные в Map.
Скачайте пример данных
Набор данных содержит 6 120 спанов трассировки OTel, экспортированных из демонстрационного микросервисного приложения. Каждая строка включает столбцы
ResourceAttributes и SpanAttributes с динамическими парами ключ-значение в формате JSON.
Сохраните файл в каталог, путь к которому вам будет удобно использовать, например ~/data/data-otel-traces.csv.Скачать data-otel-traces.csv (2.9 MB)Вот как выглядит одна строка:Создайте таблицу и загрузите данные
Запустите Теперь загрузите CSV с помощью движка таблицы Убедитесь, что данные загружены:Вы должны увидеть 6 120 строк.
clickhouse-local и создайте следующую таблицу со схемой, соответствующей CSV.
Ключевой столбец — ResourceAttributes Map(LowCardinality(String), String); LowCardinality используется для типа ключа, поскольку ключи атрибутов OTel берутся из относительно небольшого набора повторяющихся значений.file. Укажите путь к файлу, который вы сохранили:Запросите данные
Доступ к конкретному ключу — используйте синтаксис с квадратными скобками, чтобы получить значение из Фильтрация по значению в map — найдите все спаны с определённым именем сервиса:Проверьте, есть ли ключ — не каждый span содержит метаданные Kubernetes. Используйте Проверьте все ключи, встречающиеся во всём наборе данных — это полезно, чтобы понять, что именно создаёт инструментирование:Разверните Map в строки с помощью ARRAY JOIN — превратите каждую пару ключ-значение в отдельную строку — это удобно для составления перечней атрибутов или наполнения панелей мониторинга:Фильтруйте maps с помощью mapFilter — извлекайте из каждого спана только атрибуты, связанные с Kubernetes:Находите спаны с ошибками и их ресурсный контекст — сочетайте обычные фильтры по столбцам с доступом к Map:
Map. Если в данной строке такого ключа нет, будет возвращено значение по умолчанию для типа значения (пустая строка для String):mapContains, чтобы найти те, у которых они есть:Агрегирование по Map с помощью комбинатора -Map
Агрегатный комбинатор Теперь используйте Суффикс Вы также можете комбинировать его с другими комбинаторами. Например, Почему это важно для OTel: Когда ваш OTel Collector записывает в ClickHouse поминутную разбивку по кодам статуса,
-Map в ClickHouse позволяет применять любую агрегатную функцию к столбцу типа Map, при этом она выполняется отдельно для каждого ключа. Результатом тоже будет Map — по одной записи на ключ с агрегированным значением. Это особенно полезно для метрик OTel, где значения Counter или Gauge хранятся в Map.Чтобы продемонстрировать это, создайте небольшую таблицу метрик, в которой каждая строка содержит количества HTTP-кодов состояния в виде Map(String, UInt64):sumMap, чтобы суммировать количество по каждому коду статуса для каждого сервиса:-Map работает с любой агрегатной функцией, поэтому вы можете так же легко использовать minMap, maxMap или avgMap:sumMapIf позволяет выполнять условную агрегацию — в данном случае суммируются только те минутные окна, в которых у сервиса уже были ошибки:sumMap позволяет агрегировать её в почасовые или суточные итоги одним запросом — без ARRAY JOIN, без разворота в строки и без необходимости заранее знать полный набор ключей. Любой ключ, встречающийся хотя бы в одной строке, автоматически включается в результат.Оптимизируйте работу с часто используемыми в запросах ключами
Если вам постоянно приходится фильтровать данные по одному и тому же ключу в 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).
Что дальше
- Создайте свою первую таблицу семейства MergeTree
- Создайте свое первое materialized view
- Типичные проблемы при начале работы
