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

ClickHouse 24.8 LTS: тестируем Iceberg-таблицы из S3 без ETL

Обновили аналитический кластер до ClickHouse 24.8 LTS. Проверяем чтение Iceberg-таблиц прямо из объектного хранилища - без ETL-пайплайна. Первые замеры и подводные камни.

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

ClickHouse 24.8 LTS вышел с улучшенным планировщиком запросов, поддержкой Delta Lake и Iceberg как внешних таблиц

ClickHouse 24.8 получил статус LTS - а это, по классике жанра, сигнал: можно переходить с «потестируем как-нибудь» на «ставим в прод». Мы дождались 24.8.3 (третий патч-релиз в ветке) и прокатили обновление на аналитическом кластере. Главное, что хотелось проверить - поддержка Iceberg как внешней таблицы: читать данные прямо из объектного хранилища, не перегоняя через ETL.

Что приехало в 24.8

Несколько пунктов из release notes, которые нас реально интересовали.

Улучшенный планировщик запросов. В 24.8 переработана внутренняя модель планирования для запросов с JOIN и подзапросами. Конкретно - улучшена оценка кардинальности и порядок соединений при join нескольких таблиц разного размера. На наших типовых аналитических запросах (событийные таблицы с несколькими dimension-таблицами) это проявляется в более разумных планах без ручных подсказок через SETTINGS join_algorithm.

Delta Lake и Iceberg как внешние таблицы. Это и есть главный интерес. ClickHouse теперь умеет работать с Iceberg-таблицами через движки IcebergS3, IcebergAzure, IcebergLocal. Данные остаются в объектном хранилище, ClickHouse читает метаданные формата и напрямую обращается к parquet-файлам. Никакого ETL-пайплайна для загрузки в MergeTree - просто создаём внешнюю таблицу и делаем SELECT.

Параллельные реплики - доработки. Механизм параллельного чтения с реплик (allow_experimental_parallel_reading_from_replicas) переработан: убраны несколько случаев, когда параллелизм включался там, где не стоило, и портил время ответа вместо улучшения. Мы этот режим использовали осторожно именно из-за его непредсказуемости - посмотрим, стало ли стабильнее.

Как обновляли кластер

Кластер - три шарды по два реплики, версия 24.3 LTS. Обновление шло по стандартной схеме: по одному хосту, через clickhouse-server stop / замена пакетов / clickhouse-server start, с проверкой что реплика дотягивает данные прежде чем переходим к следующему. ClickHouse достаточно лояльно переживает rolling update между совместимыми версиями.

Единственный момент, который потребовал внимания - изменение формата нескольких системных таблиц в system.query_log. Наш Grafana-дашборд с аналитикой медленных запросов сломался сразу после обновления: один из столбцов сменил тип. Поправили запрос в дашборде, делов на пять минут, но неприятно когда мониторинг слепнет в момент обновления именно системы мониторинга.

Iceberg: что получилось

Тестовый стенд - S3-совместимое объектное хранилище (внутри контура), несколько Iceberg-таблиц, созданных через Apache Spark. Размер таблиц от 50 ГБ до ~300 ГБ, партиционирование по дате, формат данных - parquet с zstd-компрессией.

Создание внешней таблицы выглядит так:

CREATE TABLE events_iceberg
ENGINE = IcebergS3(
    's3://bucket/warehouse/events/',
    'access_key', 'secret_key'
);

ClickHouse читает metadata/ директорию Iceberg, разбирается в снепшотах и manifest-файлах, строит список parquet-файлов для чтения. SELECT работает.

Что хорошо. Простые аналитические запросы с фильтрацией по партиционированным полям работают быстро - ClickHouse корректно pruning-ует партиции на уровне Iceberg-метаданных и не читает лишние файлы. Запрос по конкретной дате на 300-гигабайтной таблице - несколько секунд, что сопоставимо с аналогичным запросом в нативном MergeTree при той же избирательности.

Что медленно. Запросы без фильтра по партиционному ключу - полное сканирование всех parquet-файлов через S3. Скорость упирается в пропускную способность канала к объектному хранилищу и накладные расходы на HTTP-запросы к каждому файлу. На 300 ГБ без партиционирования - от нескольких минут. Для ad hoc запросов типа «посмотреть пример данных» это приемлемо, для регулярной аналитики - нет.

Подводные камни. Первый и самый неожиданный - версионирование метаданных Iceberg. Если Spark в момент SELECT-а пишет новый снепшот (а это происходит при каждом INSERT OVERWRITE или MERGE), ClickHouse может поймать промежуточное состояние и вернуть ошибку чтения. Iceberg изолирован на уровне снепшотов только для читателей, которые явно работают с конкретным snapshot_id - ClickHouse-движок в 24.8 использует «последний снепшот» и делает это не атомарно относительно записи. Решение - читать в окнах, когда записи нет, или ждать пока ClickHouse добавит явную работу со snapshot_id (в docs есть issue, пока открытый).

Второй момент - схема. IcebergS3 не поддерживает в 24.8 evolution схемы: если Iceberg-таблица имеет несколько исторических версий схемы (добавляли новые столбцы в разные периоды), ClickHouse может прочитать данные некорректно или упасть с ошибкой на старых parquet-файлах. Наш тестовый датасет был создан «с нуля» без эволюции - проблема не проявилась, но для production-данных это важное ограничение.

Планировщик запросов: стало ли лучше

Да, на некоторых запросах заметно. Конкретный кейс - JOIN событийной таблицы (~2 млрд строк) с тремя dimension-таблицами (от 50 тысяч до 5 млн строк). В 24.3 план периодически выбирал неоптимальный порядок JOIN и запрос отрабатывал вдвое дольше ожидаемого. В 24.8 тот же запрос без изменений в SQL стабильно выбирает правильный порядок. Не везде, но конкретно здесь - улучшение реальное.

Где сейчас

Кластер работает на 24.8 LTS уже две недели, инцидентов нет. Iceberg-чтение переведено в «инструмент для аналитиков при работе с freshly-landed данными» - то есть для разведочных запросов и проверки данных до того, как они прогонятся через основной пайплайн в DWH. Заменить ETL полностью не получается из-за ограничений с эволюцией схемы и поведением при конкурентной записи.

За планировщиком запросов будем наблюдать - там ещё много пространства для улучшений при сложных аналитических запросах, и каждое улучшение здесь имеет прямой экономический смысл.

Контакт

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

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