ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

ClickHouse 26.5 + Apache Iceberg: federated query без ETL и сколько это реально стоит

ClickHouse 26.5 улучшил query cache и добавил полноценную поддержку Iceberg для внешних таблиц. Тестируем federated query на нашем кластере и замеряем overhead.

Контекст момента

ClickHouse 26.5 вышел с улучшенным query cache и поддержкой Apache Iceberg для внешних таблиц

ClickHouse 26.5 вышел на прошлой неделе. Два изменения сразу попали в поле нашего внимания: переработанный query cache и расширенная поддержка Apache Iceberg для внешних таблиц. Второе - в первую очередь, потому что именно с Iceberg у нас давний незакрытый счёт.

В апреле мы описывали как строили lakehouse на ClickHouse + MinIO + Iceberg и сколько вспомогательного кода пришлось написать, чтобы всё работало. Одна из главных болей - ClickHouse умел читать Iceberg-таблицы, но не умел делать это в режиме полноценного federated query: нельзя было объединить данные из нативной ClickHouse-таблицы и Iceberg-таблицы в одном запросе без предварительного ETL или materialised view. Точнее, технически JOIN работал, но partition pruning на стороне Iceberg отваливался, и запрос читал всё подряд.

Что изменилось в 26.5

Поддержка Iceberg стала полноценной внешней таблицей. В 26.5 движок IcebergS3 получил нормальный pushdown предикатов, включая сложные фильтры по партиционированным полям. Теперь ClickHouse смотрит на Iceberg-манифесты и partition summary прежде чем идти за файлами, и транслирует WHERE-условия в pruning на уровне Iceberg partition spec. Включая bucket() и truncate() трансформации - как раз то, на чём мы спотыкались раньше.

Query cache стал умнее в сценариях с внешними таблицами. До 26.5 query cache работал только для запросов полностью к нативным MergeTree-таблицам - логично, потому что для внешних источников кеш рисковал отдавать устаревшие данные без предупреждения. В 26.5 добавили TTL-based invalidation привязанный к snapshot ID Iceberg-таблицы: кеш хранит вместе с результатом snapshot, при котором он был получен, и инвалидирует запись при появлении нового snapshot. Не универсальное решение - оно работает только там, где ClickHouse видит Iceberg-метаданные, но для нашего сценария это именно то, что нужно.

Что тестировали

На нашем аналитическом кластере живут две категории данных: горячие - нативные ClickHouse MergeTree-таблицы с данными за последние 90 дней, и холодные - исторический архив в Iceberg/MinIO с полной историей за несколько лет. До 26.5 запросы «дай мне тренд за 2 года» шли в два шага: сначала выгрузка из Iceberg через отдельный pipeline, потом JOIN уже внутри ClickHouse с нативными данными. Это или ручной ETL, или сложный orchestration.

После обновления на 26.5 написали тестовый запрос который напрямую объединяет нативную таблицу с Iceberg-внешней:

SELECT
    toStartOfMonth(event_time) AS month,
    sum(amount) AS total
FROM native_events
UNION ALL
SELECT
    toStartOfMonth(event_time) AS month,
    sum(amount) AS total
FROM iceberg_s3('...', 'events')
WHERE event_time < toDate('2026-01-01')
GROUP BY month
ORDER BY month

Partition pruning. На запросе с конкретным диапазоном дат ClickHouse теперь реально читает только нужные Iceberg-партиции. На нашей тестовой таблице с партицией по месяцам и запросом за год - сканирует 12 файловых групп вместо всего архива. Раньше читал всё. Разница в прочитанных байтах из MinIO - кратная.

Overhead на первый запрос. Новый pushdown требует парсинга Iceberg-манифестов до начала чтения данных. На больших таблицах с тысячами snapshot-файлов это добавляет заметную задержку перед началом streaming результата. На нашей таблице с ~800 manifest entries это около 1-2 секунд дополнительно к первому запросу. Для интерактивного BI это граница приемлемого; для пакетных запросов - не проблема совсем.

Query cache на Iceberg. Включили с TTL в 5 минут. При повторных запросах к одному snapshot - кеш работает и отдаёт результат мгновенно. При появлении нового snapshot в Iceberg-таблице (у нас compaction запускается раз в 30 минут) - кеш инвалидируется автоматически. Раньше мы городили свой инвалидатор поверх application-layer кеша. Теперь это из коробки.

Что стало ненужным

Помним, что в апреле написали schema-sync daemon для автоматической синхронизации схемы между Iceberg и ClickHouse? В 26.5 добавили REFRESH PERIODICALLY опцию для внешних Iceberg-таблиц - движок сам опрашивает catalog по расписанию и подхватывает новые колонки. Daemon мы ещё не выключили (хочется понаблюдать поведение в разных ситуациях), но по всей видимости это убираемый компонент.

Осторожность, которую не стоит отбрасывать

Federated query между нативным ClickHouse и Iceberg теперь работает удобно, но несколько вещей надо держать в голове.

Первое - network cost. Каждый query к Iceberg-данным в MinIO - это трафик между ClickHouse-нодами и object storage. Даже с pruning это реальная нагрузка на сеть. При высокой конкурентности запросов у нас начинает проявляться contention на сетевом интерфейсе storage-ноды.

Второе - catalog latency. Если Iceberg catalog (у нас REST catalog на PostgreSQL) недоступен или медленный - весь запрос ждёт. Это новая точка зависимости, которой не было при работе только с нативными таблицами.

Третье - snapshot consistency. JOIN между нативной таблицей (данные на момент запроса) и Iceberg-таблицей (данные на момент последнего snapshot) - это разные временные срезы. Для большинства аналитических сценариев это нормально, но надо понимать, что пишешь запрос, который по природе eventually consistent.

Где мы сейчас

Обновление выглядит убедительно для наших сценариев. ETL-pipeline который гонял данные из Iceberg в staging-таблицу перед JOIN - планируем убрать. Это уменьшит и сложность, и latency для запросов типа «вся история».

Query cache на Iceberg включаем в продуктиве - это прямой выигрыш для BI-дашбордов которые читают исторические данные за фиксированный период.

Schema-sync daemon оставляем под наблюдением ещё несколько недель.

Про остальное в 26.5 (новые функции для работы с временными рядами, изменения в replicated DDL) - пишите если интересно, можем разобрать отдельно.

Если строите аналитическую платформу с lakehouse-архитектурой - DWH/BI-проекты это как раз та область, где мы работаем с такими стеками в продуктиве.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.