Перейти к содержанию
Learning Platform
Глоссарий Troubleshooting
Урок 15.11 · 35 мин
Продвинутый
ClickStackOpenTelemetryHyperDXobservabilitylogsmetricstracessession replayclickhouseexporterotel_logsotel_tracesHelm chartClickHouse CloudManaged ClickStack

ClickStack: единый observability-стек на ClickHouse

ClickStack — это flagship observability-бандл от ClickHouse Inc., анонсированный в мае 2025 года. Стек объединяет три компонента: ClickHouse в качестве хранилища (logs/metrics/traces/session replay), OpenTelemetry Collector как ingestion-слой и HyperDX как пользовательский интерфейс. ClickStack позиционируется как открытая альтернатива DataDog, Splunk и Elastic+APM с кросс-сигнальной корреляцией на уровне БД и стоимостью хранения от трёх центов за гигабайт в месяц в Managed-варианте.

INFO

HyperDX был приобретён ClickHouse Inc. 13 марта 2025 года. На базе HyperDX UI и официального clickhouseexporter из OpenTelemetry Collector Contrib команда ClickHouse собрала единый дистрибутив, получивший имя ClickStack. Релиз GA состоялся 29 мая 2025 года; во второй половине 2025 года добавились RBAC, alerting и Managed ClickStack в облаке.


Архитектура ClickStack

Поток телеметрии в ClickStack
App + OTel SDKApplication: приложение с инструментацией OpenTelemetry SDK (auto-instrumentation для Node.js, Python, Java, .NET, Go). Эмитит logs/metrics/traces по OTLP-протоколу. Session replay — отдельный Browser SDK от HyperDX, отправляющий события напрямую в OTel Collector.
OTLP gRPC/HTTP
OTel CollectorOpenTelemetry Collector с включённым clickhouseexporter (OpenTelemetry Collector Contrib). В ClickStack идёт opinionated preset: receivers (otlp, hostmetrics), processors (batch, attributes, resource), exporters (clickhouse). Принимает все три сигнала одним процессом и пишет батчами в ClickHouse через native protocol.
native protocol :9000
ClickHouseClickHouse cluster (self-hosted) или ClickHouse Cloud. Создаются таблицы otel_logs, otel_traces, otel_metrics_sum, otel_metrics_gauge, otel_metrics_histogram, otel_metrics_exponential_histogram, otel_metrics_summary. Все таблицы используют MergeTree, ZSTD-сжатие, partitioning по toDate(timestamp), TTL для автоматического перевода старых данных в S3.
SQL/Lucene запросы
HyperDX UIHyperDX UI: Next.js-приложение, обращается к ClickHouse напрямую через HTTP-интерфейс (порт 8123), без middleware. Поддерживает Lucene-style search, SQL Editor, dashboards, trace explorer, session replay player, AI-alerts. Не требует отдельного API-сервера или query-кэша.

Ключевое архитектурное решение: HyperDX UI работает поверх ClickHouse напрямую, без посредников. Это снижает количество сервисов в production и устраняет дополнительный слой кэширования.


Зачем единый стек: проблема трёх пиллар

Классическая модель «трёх пиллар» — logs, metrics, traces — приводит к фрагментации данных по разным backend-ам:

Three-pillar model vs ClickStack
Grafana LGTM: 3 backendsGrafana LGTM stack: Loki хранит логи (индекс по labels), Mimir/Prometheus — метрики (TSDB), Tempo — трейсы (object storage). Каждый компонент — отдельный stateful-сервис со своим scaling и retention. Корреляция между сигналами происходит на уровне Grafana UI через trace_id labels — это application-layer correlation, медленный и хрупкий.
ClickStack: один backendClickStack: одна OLAP-база ClickHouse хранит все три сигнала плюс session replay в семантически совместимых таблицах. Корреляция через обычный SQL JOIN по trace_id, span_id, ServiceName, ResourceAttributes — это database-layer correlation, быстрая и атомарная. Один backup, один retention policy, один scaling-план.

В Grafana LGTM-стеке (Loki + Tempo + Mimir) каждый сигнал живёт в своём хранилище. Чтобы перейти от лога ошибки к соответствующему трейсу, UI должен сделать lookup в Tempo по trace_id — это корреляция на уровне приложения. В ClickStack корреляция выполняется обычным SQL JOIN внутри одной БД:

-- Найти все логи и спаны конкретного запроса в одном запросе
SELECT
    'log' AS signal,
    Timestamp,
    SeverityText AS level,
    Body AS message,
    NULL AS duration_ns
FROM otel_logs
WHERE TraceId = 'a1b2c3d4e5f6...'

UNION ALL

SELECT
    'trace' AS signal,
    Timestamp,
    StatusCode AS level,
    SpanName AS message,
    Duration AS duration_ns
FROM otel_traces
WHERE TraceId = 'a1b2c3d4e5f6...'

ORDER BY Timestamp;

OpenTelemetry → ClickHouse: схема и формат данных

Официальный clickhouseexporter живёт в opentelemetry-collector-contrib и поддерживает все три сигнала. По умолчанию создаются следующие таблицы:

-- Логи: одна строка на лог-событие
CREATE TABLE otel_logs (
    Timestamp           DateTime64(9) CODEC(Delta(8), ZSTD(1)),
    TraceId             String        CODEC(ZSTD(1)),
    SpanId              String        CODEC(ZSTD(1)),
    TraceFlags          UInt32        CODEC(ZSTD(1)),
    SeverityText        LowCardinality(String) CODEC(ZSTD(1)),
    SeverityNumber      Int32         CODEC(ZSTD(1)),
    ServiceName         LowCardinality(String) CODEC(ZSTD(1)),
    Body                String        CODEC(ZSTD(1)),
    ResourceSchemaUrl   String        CODEC(ZSTD(1)),
    ResourceAttributes  Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    ScopeSchemaUrl      String        CODEC(ZSTD(1)),
    ScopeName           String        CODEC(ZSTD(1)),
    ScopeVersion        String        CODEC(ZSTD(1)),
    ScopeAttributes     Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    LogAttributes       Map(LowCardinality(String), String) CODEC(ZSTD(1)),
    INDEX idx_trace_id  TraceId TYPE bloom_filter(0.001) GRANULARITY 1,
    INDEX idx_body      Body    TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 8
)
ENGINE = MergeTree
PARTITION BY toDate(Timestamp)
ORDER BY (ServiceName, SeverityText, toUnixTimestamp(Timestamp), TraceId)
TTL toDateTime(Timestamp) + INTERVAL 30 DAY;
WARNING

Для production используйте create_schema: false в конфигурации экспортёра и создавайте таблицы вручную. Иначе несколько процессов Collector будут гонять CREATE TABLE IF NOT EXISTS параллельно, а апгрейд экспортёра становится проблемой: нужно сначала альтерить схему вручную, иначе старые писатели сломают тип. Дефолтные DDL лежат в internal/sqltemplates репозитория contrib.

Похожая схема существует для трейсов (otel_traces) и для каждого типа метрики: otel_metrics_sum, otel_metrics_gauge, otel_metrics_histogram, otel_metrics_exponential_histogram, otel_metrics_summary. Каждый тип метрики отделён, потому что у них разная форма payload.

Materialized columns для дешёвых агрегаций

Запросы вида «топ-10 endpoints по количеству ошибок за час» могут стоить дорого, если каждый раз парсить LogAttributes['http.route'] из Map. Материализованные колонки решают это:

ALTER TABLE otel_logs
    ADD COLUMN HttpRoute LowCardinality(String)
    MATERIALIZED LogAttributes['http.route'];

ALTER TABLE otel_logs
    ADD COLUMN HttpStatusCode UInt16
    MATERIALIZED toUInt16OrZero(LogAttributes['http.status_code']);

Materialized колонка вычисляется при вставке и пишется на диск как обычная колонка. Запрос GROUP BY HttpRoute теперь читает только одну компактную LowCardinality-колонку, а не полную Map.


Конфигурация OTel Collector

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 5s
    send_batch_size: 100000
  resource:
    attributes:
      - key: deployment.environment
        value: production
        action: upsert

exporters:
  clickhouse:
    endpoint: tcp://clickhouse:9000?dial_timeout=10s
    database: otel
    username: default
    password: ${CLICKHOUSE_PASSWORD}
    create_schema: false           # Production: таблицы созданы заранее
    logs_table_name: otel_logs
    traces_table_name: otel_traces
    metrics_tables:
      sum:
        name: otel_metrics_sum
      gauge:
        name: otel_metrics_gauge
      histogram:
        name: otel_metrics_histogram
    ttl: 720h                      # 30 дней (если schema создаётся экспортёром)
    timeout: 10s
    sending_queue:
      enabled: true
      num_consumers: 10
      queue_size: 100

service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [clickhouse]
    traces:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [clickhouse]
    metrics:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [clickhouse]
TIP

Используйте batch processor с send_batch_size: 100000 — ClickHouse оптимально принимает крупные батчи. Слишком частые мелкие inserts создают много мелких parts и нагружают background merge. Для backpressure включайте sending_queue — Collector будет буферизовать события, если ClickHouse временно недоступен.


HyperDX UI: что доступно из коробки

Возможности HyperDX UI
Log searchLog search: Lucene-style query (level:error AND service:api) или полный SQL Editor для сложных запросов. Live tail режим. Inline-просмотр attributes без переключения в детальный view. Сохранённые поиски и shareable URL.
Trace explorerTrace explorer: waterfall-визуализация спанов в trace, переход от лога к содержащему его трейсу одним кликом (через trace_id JOIN), span attributes, span events, ошибки спанов. Service map строится автоматически из ResourceAttributes['service.name'] и span links.
DashboardsDashboards: панели на базе SQL или Lucene. Поддержка time-series, log tables, big-number tiles, percentile-charts. Variables — выпадающие списки значений из ClickHouse (например, список ServiceName). Templating через переменные dashboard в запросах.
Alerts + AIAlerting: search-based alerts (триггер по результату Lucene-запроса) и chart-based alerts (триггер по аггрегации в дашборде). Notification channels: Slack, PagerDuty, generic webhook. Поддержка alert grouping и suppression. AI-anomaly detection в roadmap.

Session replay — отличительная фича HyperDX, унаследованная при приобретении: HyperDX SDK для браузера записывает DOM-события и пользовательские взаимодействия, отправляет их через OTel Collector, и в UI становится доступен player ровно для той сессии, в которой случилась ошибка. Запись полностью совместима с rrweb.


Развёртывание

Self-hosted: Helm chart

ClickHouse Inc. публикует официальный Helm chart в репозитории ClickHouse/clickstack-helm-charts:

# 1. Установить операторы и CRDs
helm repo add clickstack https://clickhouse.github.io/clickstack-helm-charts
helm repo update

helm install clickstack-operators clickstack/clickstack-operators \
    --namespace clickstack-system \
    --create-namespace

# 2. Установить сам ClickStack (CH + OTel Collector + HyperDX)
helm install my-clickstack clickstack/clickstack \
    --namespace clickstack \
    --create-namespace \
    --set hyperdx.ingress.enabled=true \
    --set hyperdx.ingress.host=hyperdx.example.com

Чарт разворачивает: StatefulSet для ClickHouse (или ClickHouse Operator с шардированием), Deployment для OTel Collector с автоскейлингом, Deployment для HyperDX UI, Ingress, Secrets для credentials.

Managed ClickStack в ClickHouse Cloud

С конца 2025 года в ClickHouse Cloud доступен Managed ClickStack (beta) — onboarding одной кнопкой: Cloud сам разворачивает Collector endpoint, создаёт схему и подключает HyperDX UI к существующему сервису. Цена позиционируется как «менее трёх центов за гигабайт в месяц» (включая хранение, сжатие и compute для запросов), что делает решение конкурентным DataDog при удержании full-fidelity high-cardinality данных.


Storage layout: TTL, hot/cold, codecs

ClickStack использует тот же арсенал ClickHouse, что и обычные аналитические таблицы, но с настройками, оптимизированными для observability:

-- Production-схема логов с hot/cold S3 tiered storage
CREATE TABLE otel_logs (
    Timestamp     DateTime64(9) CODEC(Delta(8), ZSTD(1)),
    ServiceName   LowCardinality(String) CODEC(ZSTD(1)),
    SeverityText  LowCardinality(String) CODEC(ZSTD(1)),
    Body          String        CODEC(ZSTD(3)),
    TraceId       String        CODEC(ZSTD(1)),
    -- ...
    LogAttributes Map(LowCardinality(String), String) CODEC(ZSTD(1))
)
ENGINE = MergeTree
PARTITION BY toStartOfHour(Timestamp)         -- Маленькие партиции для precision-TTL
ORDER BY (ServiceName, SeverityText, Timestamp)
TTL
    Timestamp + INTERVAL 7 DAY  TO VOLUME 'cold',  -- 7 дней hot SSD -> cold S3
    Timestamp + INTERVAL 90 DAY DELETE             -- 90 дней total retention
SETTINGS storage_policy = 'hot_cold';

Ключевые приёмы:

  • LowCardinality(String) для ServiceName, SeverityText, ключей в ResourceAttributes. Эти поля имеют десятки уникальных значений на терабайт логов — компрессия x10-x50.
  • ZSTD(1) — дефолт для текстовых полей. ZSTD(3) для Body даёт ещё ~15% компрессии при terпимом увеличении CPU.
  • Delta(8) + ZSTD для DateTime64(9) — хорошо упаковывает последовательные timestamps.
  • PARTITION BY toStartOfHour(Timestamp) — позволяет TTL-движку перемещать парты между volumes гранулярнее, чем дневные партиции.
  • Bloom filter index на TraceId и token bloom filter на Body — ускоряют lookup без full scan.
NOTE

В сравнении с Elasticsearch ClickStack даёт сжатие 10-30× на тех же логах. Сценарий: 100 ТБ raw-логов сжимаются до 5-10 ТБ в ClickHouse и до 30-50 ТБ в Elastic. Это базовая экономика, на которой строится тезис «менее трёх центов за гигабайт» в Managed ClickStack.


ClickStack vs альтернативы

Сравнение ключевых open-source и SaaS observability-стеков:

КритерийClickStackGrafana LGTM (Loki + Tempo + Mimir)Elastic + APMDataDog (SaaS)
Backends для 3 сигналов1 (ClickHouse)3 stateful-сервиса1 (Elastic)proprietary
Корреляция logs/tracesDB-level (SQL JOIN)App-level (trace_id lookup)App-levelApp-level
ЗапросыLucene + полный SQLLogQL/PromQL/TraceQLKQL/EQLproprietary DSL
Сжатие vs raw10-30×5-10× (Loki)3-5×n/a (SaaS billing)
Open sourceApache 2.0AGPLv3 / Apache 2.0SSPL/Elastic L.proprietary
Self-hosted сложностьHelm, 1 chart3 отдельных stateful + GrafanaCluster + APMn/a
Managed offeringClickHouse Cloud (beta)Grafana CloudElastic CloudDataDog (native)
Session replayNative (HyperDX)Faro (отдельно)RUM (отдельно)RUM (включён)
Стоимость high-cardinalityНизкая (columnar)Средняя (Loki плох с метками)ВысокаяОчень высокая

ClickStack выигрывает там, где важны: единое хранилище, кросс-сигнальный SQL, дешёвое хранение high-cardinality атрибутов, контроль над инфраструктурой. Grafana LGTM остаётся сильным выбором для команд, у которых уже есть экспертиза в Prometheus/PromQL и которым нужна best-in-class визуализация. DataDog стоит выбирать, если нужен полностью managed опыт без операционной нагрузки — за заметную премию в счёте.


Текущие ограничения ClickStack (актуально на конец 2025)

Стек активно развивается; на момент апреля 2026 года стоит знать о следующих границах:

WARNING

RBAC появился в ClickStack осенью 2025: роли (no access / read / manage) для dashboards, saved searches, sources, alerts, webhooks, notebooks. Fine-grained access rules позволяют скрывать ресурсы от конкретных команд. На момент анонса RBAC доступен в Managed ClickStack и в self-hosted Enterprise-варианте; в OSS-сборке часть ролей упрощена.

Alerting доступен в Managed ClickStack для ClickHouse Cloud: search-based и chart-based alerts, интеграции со Slack, PagerDuty, generic webhook. Email и anomaly detection в roadmap. В self-hosted OSS-сборке alerting развёртывается отдельным компонентом.

Multi-tenancy реализован через RBAC + row-level security в ClickHouse: одна инсталляция HyperDX может обслуживать несколько команд через row-policies на ServiceName / namespace, но «жёсткий» tenant isolation (отдельные query-пулы, биллинг, лимиты) пока в roadmap Managed-варианта.

Также стоит понимать, что ClickStack — не turnkey-решение в стиле DataDog: в self-hosted-варианте требуется обслуживать ClickHouse-кластер (merges, ZooKeeper/Keeper, backups), настраивать OTel Collector pipeline и иногда вручную тюнить схему под конкретные нагрузки.


Production-чеклист

Перед деплоем ClickStack в production проверьте:

  1. Схема создана вручную: create_schema: false в clickhouseexporter, DDL версионируется в репозитории миграций (например, golang-migrate или сам ClickHouse keeper).
  2. TTL и storage policy: определены hot tier (NVMe/SSD, 3-14 дней), cold tier (S3, до 90-180 дней), DELETE-TTL для соответствия GDPR/PCI.
  3. Materialized columns для частых GROUP BY атрибутов (HttpRoute, HttpStatusCode, KubernetesNamespace).
  4. Bloom filters на TraceId, SpanId; tokenbf на Body если есть полнотекстовый поиск.
  5. OTel Collector batch settings: send_batch_size >= 50000, timeout 5-10s, sending_queue.enabled: true для backpressure.
  6. Replicated ClickHouse (минимум 2 реплики на шард), Keeper-ансамбль из 3 нод, регулярные backups через BACKUP DATABASE otel TO S3(...).
  7. Resource attributes whitelist на уровне Collector: attributes processor с include режимом, чтобы не разрастались уникальные ключи в Map.
  8. Алерты на саму инфраструктуру: system.errors, system.replicas.is_readonly, размер otel_logs parts, отставание Collector queue.

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

  1. ClickStack — flagship observability bundle от ClickHouse Inc., анонсирован в мае 2025 после приобретения HyperDX в марте 2025. Состоит из ClickHouse (хранилище), OTel Collector с clickhouseexporter (ingestion) и HyperDX UI (фронтенд).
  2. Кросс-сигнальная корреляция на уровне БД — главное архитектурное преимущество. Logs/metrics/traces/session replay живут в одной OLAP-базе и соединяются обычным SQL JOIN по TraceId/ServiceName, а не через application-layer lookup.
  3. OpenTelemetry — единственный путь ingestion. Стандартные таблицы otel_logs, otel_traces, otel_metrics_* создаются clickhouseexporter из collector-contrib. В production используйте create_schema: false и собственный DDL.
  4. HyperDX UI работает поверх ClickHouse напрямую, без middleware и API-сервера. Поддерживает Lucene-style search, полный SQL, dashboards, trace explorer, session replay player и alerting (search-based + chart-based).
  5. Storage layout оптимизирован под observability: LowCardinality(String) для атрибутов, ZSTD codec, PARTITION BY toStartOfHour, TTL для hot/cold (S3) tiers, materialized columns для частых GROUP BY, bloom filters на TraceId и Body.
  6. Развёртывание: self-hosted через Helm chart (ClickHouse/clickstack-helm-charts) или Managed ClickStack в ClickHouse Cloud (beta, цена от трёх центов за гигабайт в месяц с full-fidelity high-cardinality удержанием).
  7. Сравнение: ClickStack даёт 10-30× сжатие vs Elastic, DB-level корреляцию vs application-level в Grafana LGTM, и контроль над инфраструктурой при существенно меньшей TCO по сравнению с DataDog для high-cardinality нагрузок.
  8. Текущие ограничения (конец 2025): RBAC, alerting, multi-tenancy появились во второй половине 2025 и продолжают развиваться. Self-hosted OSS-сборка отстаёт по этим возможностям от Managed ClickStack в облаке.
Observability в data системах: signals, correlation и SLO Avro + OpenTelemetry Kafka exporter: schema и wire format
TIP

Для практики разверните ClickStack локально через Helm в kind/k3d-кластере: helm install my-clickstack clickstack/clickstack. Сгенерируйте нагрузку OpenTelemetry demo-приложением (otel-demo) и попробуйте написать SQL-запрос, который соединяет otel_logs и otel_traces по TraceId — это базовый паттерн root-cause-анализа в ClickStack.

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 12