Learning Platform
Глоссарий Troubleshooting
Урок 16.06 · 30 мин
Продвинутый
PostHogCloudflareGitLabwide flat tablesKafka ingestiondenormalization

Архитектуры на ClickHouse: PostHog, Cloudflare, GitLab

ClickHouse используется в production у сотен компаний. Три крупнейших публичных case study — PostHog, Cloudflare и GitLab — демонстрируют повторяющиеся архитектурные паттерны: широкие плоские таблицы, Kafka для ingestion, агрессивная денормализация и TTL для управления жизненным циклом данных.


PostHog: шардированный кластер для product analytics

PostHog — open-source продуктовая аналитика с само-хостингом. Их ClickHouse-кластер хранит события поведения пользователей в масштабе.

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

  • Шардированный кластер: несколько узлов с горизонтальным масштабированием
  • Kafka pull model: PostHog использует Kafka engine в ClickHouse для pull-чтения из Kafka-топиков (не push через HTTP). Materialized view записывает данные в основные таблицы
  • ReplacingMergeTree для профилей пользователей: person profiles требуют дедупликации — при обновлении свойств пользователя вставляется новая версия, старая вытесняется при merge
  • Агрессивная дедупликация: OPTIMIZE TABLE FINAL используется на небольших таблицах; для production масштаба — SELECT ... FINAL или дедупликация через приложение
-- Kafka engine для pull ingestion (PostHog-like паттерн)
CREATE TABLE events_kafka_queue
(
    uuid        String,
    team_id     UInt32,
    event       String,
    properties  String,    -- JSON-строка
    timestamp   DateTime64(3)
)
ENGINE = Kafka()
SETTINGS
    kafka_broker_list    = 'kafka:9092',
    kafka_topic_list     = 'clickhouse_events',
    kafka_group_name     = 'clickhouse-consumer',
    kafka_format         = 'JSONEachRow';

-- Основная таблица событий (широкая, денормализованная)
CREATE TABLE events
(
    uuid        UUID,
    team_id     UInt32,
    event       LowCardinality(String),
    distinct_id String,
    properties  String,
    timestamp   DateTime64(3),
    -- Денормализованные свойства для быстрых фильтров
    browser     LowCardinality(String) MATERIALIZED
        JSONExtractString(properties, '$browser'),
    os          LowCardinality(String) MATERIALIZED
        JSONExtractString(properties, '$os'),
    country     LowCardinality(String) MATERIALIZED
        JSONExtractString(properties, '$geoip_country_code')
)
ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (team_id, toDate(timestamp), event, uuid)
TTL toDate(timestamp) + INTERVAL 2 YEAR;

-- Materialized view: Kafka queue -> основная таблица
CREATE MATERIALIZED VIEW events_mv TO events AS
SELECT
    toUUID(uuid)                AS uuid,
    team_id,
    event,
    JSONExtractString(properties, 'distinct_id') AS distinct_id,
    properties,
    timestamp
FROM events_kafka_queue;

-- Person profiles: ReplacingMergeTree для дедупликации по версии
CREATE TABLE person
(
    team_id         UInt32,
    id              UUID,
    created_at      DateTime64(3),
    properties      String,    -- JSON-строка с атрибутами
    version         UInt64     -- монотонно возрастает при каждом update
)
ENGINE = ReplacingMergeTree(version)
ORDER BY (team_id, id);

Паттерн multi-tenancy через RBAC: Каждый PostHog team_id изолируется через CREATE ROW POLICY — tenant видит только свои данные.


Cloudflare: 6 миллионов запросов в секунду

Cloudflare использует ClickHouse для bot management, customer dashboards и real-time network analytics. Масштаб: более 6M RPS на пике.

Ключевые архитектурные решения:

  • Columnar performance: ClickHouse обрабатывает HTTP-запросы с признаками (IP-адрес, User-Agent, заголовки, геолокация) в одной широкой строке. Колоночное хранение позволяет сканировать только нужные атрибуты бота
  • Real-time customer dashboards: Клиенты Cloudflare видят свой трафик с задержкой менее 1 минуты через pre-aggregated materialized views
  • Многоуровневый MergeTree: Горячие данные (последние 24 часа) на быстрых NVMe SSD, архивные данные в S3 через tiered storage (JBOD + S3)
-- Упрощённая схема запроса HTTP-событий (Cloudflare-like)
CREATE TABLE http_requests
(
    -- Ключевые измерения
    zone_id         UInt32,
    client_ip       IPv4,
    ray_id          UInt64,
    request_time    DateTime64(3),

    -- Bot detection features (денормализованы для скорости)
    user_agent      String,
    cf_threat_score UInt8,
    cf_bot_score    UInt8,
    is_bot          UInt8,

    -- Геолокация
    country_code    LowCardinality(String),
    region          LowCardinality(String),

    -- HTTP метаданные
    method          LowCardinality(String),
    status_code     UInt16,
    bytes_sent      UInt32,
    edge_server_id  UInt16
)
ENGINE = MergeTree()
PARTITION BY toStartOfHour(request_time)
ORDER BY (zone_id, toDate(request_time), client_ip)
TTL request_time + INTERVAL 30 DAY;

-- Pre-aggregated view для customer dashboard (sub-second latency)
CREATE MATERIALIZED VIEW zone_hourly_stats
ENGINE = SummingMergeTree()
ORDER BY (zone_id, hour, country_code)
AS SELECT
    zone_id,
    toStartOfHour(request_time) AS hour,
    country_code,
    count()                      AS total_requests,
    sum(bytes_sent)              AS total_bytes,
    countIf(is_bot = 1)          AS bot_requests,
    countIf(status_code >= 400)  AS error_requests
FROM http_requests
GROUP BY zone_id, hour, country_code;

GitLab: sub-second queries для миллионов пользователей

GitLab — крупнейшая платформа DevOps с само-хостингом и GitLab.com. ClickHouse используется для CI/CD аналитики и метрик разработчиков.

Масштаб: Десятки миллионов пользователей, миллиарды CI/CD событий, требования к задержке ниже 1 секунды для большинства dashboard-запросов.

Архитектурные решения:

  • CI/CD аналитика: Данные о pipeline jobs, stage timings, test results — в ClickHouse вместо PostgreSQL. PostgreSQL не справлялся с аналитическими запросами при таком масштабе
  • Широкие таблицы: Pipeline job денормализован (включает данные о project, namespace, runner, stage) — исключает JOIN на горячем пути
  • Async_insert для высокого throughput: GitLab.com генерирует тысячи CI-событий в секунду; async_insert=1 буферизует вставки и снижает нагрузку на ClickHouse
-- Упрощённая схема CI/CD событий (GitLab-like)
CREATE TABLE ci_builds
(
    build_id            UInt64,
    pipeline_id         UInt64,
    project_id          UInt32,
    namespace_id        UInt32,

    -- Денормализованные атрибуты проекта
    project_path        String,
    namespace_path      String,

    -- Характеристики job
    stage_name          LowCardinality(String),
    job_name            String,
    status              LowCardinality(String),   -- success/failed/canceled
    runner_type         LowCardinality(String),   -- shared/group/project

    -- Временные метки
    created_at          DateTime,
    started_at          DateTime,
    finished_at         DateTime,
    duration_seconds    Float32 MATERIALIZED
        if(finished_at > started_at,
           dateDiff('second', started_at, finished_at),
           NULL)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(created_at)
ORDER BY (project_id, created_at, build_id)
TTL created_at + INTERVAL 3 YEAR;

-- Запрос: среднее время сборки по проекту за последние 30 дней
SELECT
    project_path,
    stage_name,
    avg(duration_seconds)           AS avg_duration,
    quantile(0.95)(duration_seconds) AS p95_duration,
    countIf(status = 'failed')      AS failed_count,
    count()                         AS total_count
FROM ci_builds
WHERE created_at >= now() - INTERVAL 30 DAY
  AND status IN ('success', 'failed')
GROUP BY project_path, stage_name
ORDER BY avg_duration DESC
LIMIT 20;

Общие паттерны production-архитектур

ClickHouse production: 3 ключевых архитектуры
PostHogPostHog: Kafka pull model через Kafka engine + MV. ReplacingMergeTree для person profiles с дедупликацией по version. RBAC ROW POLICY для multi-tenant изоляции. Агрессивная денормализация событий с MATERIALIZED колонками.
CloudflareCloudflare: 6M RPS bot management. Широкие HTTP request таблицы с всеми bot-detection признаками. Pre-aggregated SummingMergeTree MV для customer dashboards. Tiered storage: NVMe для горячих данных, S3 для архива.
GitLabGitLab: CI/CD аналитика заменила PostgreSQL для аналитических запросов. Денормализованные широкие таблицы исключают JOIN на горячем пути. async_insert=1 для высокого throughput вставок. Sub-second queries для миллионов пользователей.

Повторяющиеся паттерны во всех трёх архитектурах:

Широкие плоские таблицы: Вместо 3NF нормализации — денормализованные события с повторяющимися атрибутами. ClickHouse компрессирует повторяющиеся значения лучше, чем JOIN-операции при каждом запросе.

-- Anti-pattern: JOIN на горячем пути запроса
SELECT e.event, u.country, p.name
FROM events e
JOIN users u ON e.user_id = u.id
JOIN projects p ON e.project_id = p.id
WHERE e.ts >= now() - INTERVAL 1 HOUR;

-- ClickHouse pattern: денормализованная таблица, нет JOIN
SELECT event, user_country, project_name
FROM events_denormalized
WHERE ts >= now() - INTERVAL 1 HOUR;

Kafka engine pull model: PostHog и аналоги используют Kafka engine (ClickHouse тянет из Kafka) вместо Kafka Connect (внешний процесс пушит в ClickHouse). Преимущество: нет дополнительной инфраструктуры, backpressure управляется ClickHouse.

MergeTree + TTL для data lifecycle: Все три компании используют TTL для автоматического удаления старых данных. Исключает ручные DELETE-мутации на больших таблицах.

async_insert для высокого throughput: При вставках с клиентских агентов (особенно при высоком числе параллельных источников) async_insert=1 буферизует вставки и снижает число частей на диске.


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

  1. PostHog демонстрирует стандартный паттерн product analytics: Kafka pull model через Kafka engine + MV, ReplacingMergeTree для mutable entity profiles, RBAC для multi-tenancy.

  2. Cloudflare (6M RPS) доказывает: columnar storage ClickHouse эффективнее row-based DB для real-time analytics с высокой кардинальностью. Pre-aggregated MV обеспечивают sub-second customer dashboards.

  3. GitLab показывает сценарий миграции: PostgreSQL заменён ClickHouse только для аналитических запросов (CI/CD analytics), OLTP данные остались в PostgreSQL — правильное разделение ответственности.

  4. Широкие плоские таблицы + агрессивная денормализация — универсальный паттерн. ClickHouse компрессирует повторяющиеся значения в колонках эффективно; JOIN overhead при каждом запросе дороже дублирования данных.

  5. Kafka + async_insert + TTL — тройная основа production-архитектур с высоким throughput: Kafka для надёжного ingestion, async_insert для сглаживания пиков, TTL для автоматического жизненного цикла данных.

OLAP-платформы: архитектурные паттерны Snowflake, BigQuery, Redshift Денормализация для OLAP: wide tables, precomputed joins и компромиссы

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 3. PostHog хранит профили пользователей (person profiles) в ClickHouse. При каждом обновлении свойств пользователя вставляется новая версия записи. Какой движок используется для автоматической дедупликации по версии при merge?

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

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

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

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