ClickHouse и OLAP на собеседовании Data Engineer

Зачем DE спрашивают про ClickHouse и OLAP

ClickHouse — column-oriented OLAP-СУБД, созданная в Яндексе. Используется в Яндексе, Ozon, Avito, Wildberries, многих других — основной инструмент для real-time аналитики на больших объёмах. Типичная нагрузка: миллиарды строк, аналитические запросы, materialized views.

На собесе Data Engineer ClickHouse — частый блок в командах с большой data-стек. Уровень: junior — знает основы синтаксиса; middle — понимает MergeTree, partitioning; senior — спроектирует cluster с replication, ReplacingMergeTree для CDC.

Column-store vs row-store

Row-store (PostgreSQL, MySQL): данные хранятся построчно. Хорошо для OLTP — частые INSERT/UPDATE, поиск конкретной строки.

Column-store (ClickHouse, Snowflake, BigQuery): данные хранятся по колонкам. Хорошо для OLAP — агрегаты по колонкам, чтение преобладает.

Преимущества column-store:

  • Compression. Однотипные данные сжимаются в 10×+
  • Чтение только нужных колонок. SELECT col1, col2 не читает остальные
  • SIMD-инструкции. Vectorized execution

Недостатки:

  • Медленный point-lookup
  • Не для OLTP
  • INSERT по одной строке плохо — нужны batch

MergeTree и его варианты

MergeTree — основной engine ClickHouse. Особенности:

  • Partitioning по дате/значению — куски данных разделены физически
  • Sorting по primary key — данные внутри parts отсортированы
  • Sparse index — индекс не на каждую строку, а каждые N (по default 8192)
  • Merge — фоновое слияние малых parts в большие

Варианты:

  • ReplicatedMergeTree — репликация через ZooKeeper/Keeper
  • ReplacingMergeTree — дедупликация по primary key (последнее значение)
  • SummingMergeTree — автоматическое суммирование при merge
  • AggregatingMergeTree — кастомные агрегатные функции при merge
  • CollapsingMergeTree — для CDC: pair record(sign=1) + cancel(sign=-1) = пусто
  • VersionedCollapsingMergeTree — CollapsingMergeTree с version column

Partitioning

В ClickHouse partition — физически отдельный directory на диске. Обычно по toYYYYMM(date) или toDate(date).

Зачем:

  • Pruning при запросах по дате — читать только нужные partitions
  • TTL и удалениеDROP PARTITION мгновенный
  • Параллелизация — каждая partition обрабатывается отдельно

Размер partition: баланс. Слишком много мелких — overhead. Слишком мало больших — нет pruning.

Primary key и sorting

В ClickHouse PK ≠ unique key. PK — это sorting key: данные хранятся отсортированными по PK.

Хороший PK:

  • Колонки, по которым часто фильтруют
  • Низкая cardinality в первой колонке, увеличивая дальше
  • Обычно: (user_id, event_time) или (date, user_id)

Sparse index: ClickHouse не хранит индекс на каждую строку, а каждые N (granularity, default 8192). При SELECT с фильтром по PK — pruning блоков.

Materialized views

В ClickHouse MV — это insert trigger, не lazy refresh.

CREATE MATERIALIZED VIEW mv_daily_revenue
ENGINE = SummingMergeTree
PARTITION BY toYYYYMM(DATE)
ORDER BY DATE
AS SELECT toDate(event_time) AS DATE, sum(amount) AS revenue
FROM events
GROUP BY DATE;

При INSERT в events, ClickHouse автоматически добавляет агрегаты в MV. Запросы к MV — мгновенные, потому что данные предагрегированы.

Use cases: real-time дашборды, готовые агрегаты для частых запросов.

ReplacingMergeTree для CDC

Когда source-data меняется (UPDATE/DELETE), ReplacingMergeTree даёт дедупликацию.

CREATE TABLE orders (
    order_id Int64,
    status String,
    updated_at DateTime
)
ENGINE = ReplacingMergeTree(updated_at)
PARTITION BY toYYYYMM(updated_at)
ORDER BY order_id;

При merge в одну partition с одним order_id — оставляется запись с max updated_at.

Важно: дедупликация только при merge (асинхронно). Для актуального результата нужно FINAL в запросе или OPTIMIZE TABLE FINAL. FINAL медленный — не для production.

Альтернатива: projection или materialized view с правильной агрегацией.

Distributed tables и кластеры

ClickHouse cluster = несколько shards, каждая shard = одна или несколько replicas.

Distributed table — виртуальная таблица, маршрутизирует запросы на правильные shards.

Sharding key определяет, в какой shard писать. По default — hash, можно настроить (по user_id, по дате).

Replication — через ZooKeeper/Keeper. ReplicatedMergeTree координирует.

Quorum writes — INSERT возвращается только когда минимум N реплик записали.

Типичные вопросы

«Чем ClickHouse отличается от PostgreSQL?»

Column-store vs row-store. ClickHouse — для OLAP (агрегаты на масштабе), PostgreSQL — для OLTP (транзакции). ClickHouse не поддерживает constraints, FKs, медленный для small lookup-ов.

«Почему запрос работает 30 секунд вместо 100мс?»

(1) Нет фильтра по PK — full scan. (2) Низкая cardinality в первой колонке PK. (3) Нет partition pruning. (4) Слишком много мелких parts. (5) Неправильный engine — для CDC нужен ReplacingMergeTree.

«Когда использовать ReplacingMergeTree и его trade-off-ы?»

Для CDC-данных, где есть updates. Trade-off: дедупликация асинхронная (при merge). Запрос без FINAL может вернуть дубликаты. С FINAL — медленнее.

«Что такое materialized view в ClickHouse?»

Триггер на INSERT в исходную таблицу. При вставке в source — данные автоматически добавляются в MV. Подходит для real-time агрегации, дашбордов.

«Как масштабировать ClickHouse?»

Vertically (больше RAM/CPU) или horizontally (sharding). Sharding ключ должен быть равномерно распределённым. Репликация — для high availability.

Частые ошибки

  • Использовать ClickHouse для OLTP. Это OLAP. Для UPDATE/DELETE по одной строке — не подходит
  • INSERT по одной строке. Batch минимум 1000+ строк, иначе много мелких parts → деградация
  • Неправильный PK. Высокая cardinality в первой колонке → нет pruning
  • FINAL в production. FINAL медленный. Для актуального состояния используй другие подходы
  • Игнорировать TTL. Без TTL таблица растёт бесконечно

FAQ

ClickHouse vs Snowflake?

Оба OLAP. ClickHouse — open-source, self-hosted или managed (Cloud), низкая latency. Snowflake — fully managed, fully serverless, дороже но проще в operations.

Нужно ли уметь администрировать?

Middle — нет, basic config достаточно. Senior — желательно понимать cluster setup, replication, backup.

Какие книги?

Документация ClickHouse — главная. «ClickHouse — High-Performance Analytics» (русскоязычные авторы) — полезная для углубления.

Сколько готовиться?

С нуля — 1-2 месяца с практикой. Уже работал — 2-3 недели.

Спрашивают ли low-level (на диске storage format)?

На senior — да. Понимать parts, sparse index, merge logic.

Смотрите также