Табличная функция iceberg
Предоставляет табличный интерфейс только для чтения к таблицам Apache Iceberg, размещённым в Amazon S3, Azure, HDFS или в локальном хранилище.
Синтаксис
Аргументы
Описание аргументов совпадает с описанием аргументов табличных функций s3, azureBlobStorage, HDFS и file соответственно.
format обозначает формат файлов с данными в таблице Iceberg.
Возвращаемое значение
Таблица с указанной структурой для чтения данных из указанной таблицы Iceberg.
Пример
На данный момент ClickHouse поддерживает чтение версий v1 и v2 формата Iceberg с помощью табличных функций icebergS3, icebergAzure, icebergHDFS и icebergLocal, а также табличных движков IcebergS3, icebergAzure, IcebergHDFS и IcebergLocal.
Определение именованной коллекции
Ниже приведён пример настройки именованной коллекции для хранения URL-адреса и учётных данных:
Использование каталога данных
Таблицы Iceberg также можно использовать с различными каталогами данных, такими как REST Catalog, AWS Glue Data Catalog и Unity Catalog.
При использовании каталога большинству пользователей следует использовать движок базы данных DataLakeCatalog, который подключает ClickHouse к вашему каталогу для обнаружения ваших таблиц. Вы можете использовать этот движок базы данных вместо ручного создания отдельных таблиц с движком таблиц IcebergS3.
Чтобы использовать такие каталоги, создайте таблицу с движком IcebergS3 и укажите необходимые настройки.
Например, использование REST Catalog с хранилищем MinIO:
Либо с использованием AWS Glue Data Catalog и S3:
Эволюция схемы
На данный момент в ClickHouse можно читать таблицы Iceberg, схема которых со временем изменялась. Поддерживается чтение таблиц, в которых были добавлены и удалены столбцы, а также изменён их порядок. Можно также изменить столбец с обязательным значением на столбец, где допускается значение NULL. Кроме того, поддерживается допустимое приведение простых типов, а именно:
- int -> long
- float -> double
- decimal(P, S) -> decimal(P', S), где P' > P.
Пока невозможно изменять вложенные структуры или типы элементов внутри массивов и map.
Отсечение партиций
ClickHouse поддерживает отсечение партиций при выполнении запросов SELECT к таблицам Iceberg, что помогает оптимизировать производительность запросов за счёт пропуска не относящихся к делу файлов данных. Чтобы включить отсечение партиций, установите use_iceberg_partition_pruning = 1. Для получения дополнительной информации об отсечении партиций в Iceberg см. https://iceberg.apache.org/spec/#partitioning
Time Travel
ClickHouse поддерживает механизм time travel для таблиц Iceberg, позволяющий выполнять запросы к историческим данным по заданной метке времени или идентификатору снимка.
Обработка таблиц с удалёнными строками
В настоящее время поддерживаются только таблицы Iceberg, использующие position deletes.
Следующие методы удаления не поддерживаются:
- Equality deletes
- Deletion vectors (появились в версии 3)
Основы использования
Примечание: Нельзя указывать параметры iceberg_timestamp_ms и iceberg_snapshot_id одновременно в одном запросе.
Важные замечания
-
Снимки (snapshots) обычно создаются, когда:
-
В таблицу записываются новые данные
-
Выполняется операция компактации (compaction) данных
-
Изменения схемы обычно не создают снимки — это приводит к важным особенностям поведения при использовании time travel для таблиц, схему которых со временем изменяли.
Примеры сценариев
Во всех сценариях используется Spark, так как ClickHouse пока не поддерживает запись в таблицы Iceberg.
Сценарий 1: изменение схемы без создания новых снимков
Рассмотрим следующую последовательность операций:
Результаты запроса в разные моменты времени:
- На ts1 и ts2: отображаются только исходные два столбца
- На ts3: отображаются все три столбца; для цены первой строки указано значение NULL
Сценарий 2: различия между исторической и текущей схемой
Запрос time travel, выполненный в текущий момент времени, может показать схему, отличающуюся от текущей схемы таблицы:
Это происходит потому, что ALTER TABLE не создаёт новый snapshot, а при работе с текущей таблицей Spark берёт значение schema_id из последнего файла метаданных, а не из snapshot.
Сценарий 3: различия между исторической и текущей схемой
Второе ограничение состоит в том, что при использовании механизма time travel нельзя получить состояние таблицы до того, как в неё были записаны какие‑либо данные:
В ClickHouse поведение такое же, как в Spark. Вы можете мысленно заменить запросы SELECT в Spark на запросы SELECT в ClickHouse — и всё будет работать так же.
Определение файла метаданных
При использовании табличной функции iceberg в ClickHouse системе необходимо найти нужный файл metadata.json, который описывает структуру таблицы Iceberg. Ниже описано, как работает процесс его определения:
Поиск кандидатов (в порядке приоритета)
- Явное указание пути:
*Если вы задаёте
iceberg_metadata_file_path, система будет использовать именно этот путь, добавляя его к пути каталога таблицы Iceberg.
- При наличии этого параметра все остальные параметры разрешения пути игнорируются.
-
Сопоставление UUID таблицы: *Если указан
iceberg_metadata_table_uuid, система будет: *Смотреть только файлы.metadata.jsonв каталогеmetadata*Отбирать файлы, содержащие полеtable-uuidсо значением, совпадающим с указанным UUID (без учёта регистра) -
Поиск по умолчанию: *Если ни один из вышеперечисленных параметров не задан, все файлы
.metadata.jsonв каталогеmetadataрассматриваются как кандидаты
Выбор самого нового файла
После определения кандидатов на основе приведённых выше правил система выбирает, какой файл является самым новым:
-
Если
iceberg_recent_metadata_file_by_last_updated_ms_fieldвключён: -
Выбирается файл с наибольшим значением
last-updated-ms -
В противном случае:
-
Выбирается файл с наибольшим номером версии
-
(Версия обозначается как
Vв именах файлов форматаV.metadata.jsonилиV-uuid.metadata.json)
Примечание: Все упомянутые настройки являются настройками табличной функции (а не глобальными или на уровне запроса) и должны указываться как показано ниже:
Примечание: Хотя каталоги Iceberg обычно отвечают за разрешение метаданных, табличная функция iceberg в ClickHouse напрямую интерпретирует файлы, хранящиеся в S3, как таблицы Iceberg, поэтому важно понимать эти правила разрешения метаданных.
Metadata cache
Движок таблиц Iceberg и табличная функция Iceberg поддерживают кэш метаданных, в котором хранится информация о файлах manifest, списках manifest и JSON-файлах с метаданными. Кэш хранится в памяти. Этот функционал управляется настройкой use_iceberg_metadata_files_cache, которая по умолчанию включена.
Псевдонимы
Табличная функция iceberg теперь является псевдонимом для icebergS3.
Виртуальные столбцы
_path— Путь к файлу. Тип:LowCardinality(String)._file— Имя файла. Тип:LowCardinality(String)._size— Размер файла в байтах. Тип:Nullable(UInt64). Если размер файла неизвестен, значение —NULL._time— Время последнего изменения файла. Тип:Nullable(DateTime). Если время неизвестно, значение —NULL._etag— ETag файла. Тип:LowCardinality(String). Если ETag неизвестен, значение —NULL.
Запись в таблицы Iceberg
Начиная с версии 25.7, ClickHouse поддерживает модификацию пользовательских таблиц Iceberg.
В настоящее время это экспериментальная функция, поэтому сначала её нужно включить:
Создание таблицы
Чтобы создать собственную пустую таблицу Iceberg, используйте те же команды, что и для чтения, но явно укажите схему. Операции записи поддерживают все форматы данных из спецификации Iceberg, такие как Parquet, Avro и ORC.
Пример
Примечание: чтобы создать файл подсказки версии, включите настройку iceberg_use_version_hint.
Если нужно сжать файл metadata.json, укажите имя кодека в настройке iceberg_metadata_compression_method.
INSERT
После создания новой таблицы вы можете добавить данные, используя стандартный синтаксис ClickHouse.
Пример
DELETE
Удаление избыточных строк в формате merge-on-read также поддерживается в ClickHouse. Этот запрос создаст новый снимок (snapshot) с файлами position delete.
ПРИМЕЧАНИЕ: Если вы хотите в дальнейшем читать свои таблицы с использованием других движков Iceberg (таких как Spark), необходимо отключить настройки output_format_parquet_use_custom_encoder и output_format_parquet_parallel_encoding.
Это связано с тем, что Spark читает эти файлы по идентификаторам полей Parquet (field-id), в то время как ClickHouse в настоящее время не поддерживает запись этих идентификаторов при включённых флагах.
Мы планируем исправить это поведение в будущем.
Пример
Эволюция схемы
ClickHouse позволяет добавлять, удалять или изменять столбцы с простыми типами данных (не типа Tuple, Array или Map).
Пример
Компакция
ClickHouse поддерживает компактацию таблиц Iceberg. В данный момент он может объединять файлы position delete с файлами данных с одновременным обновлением метаданных. Идентификаторы и метки времени предыдущих snapshot остаются без изменений, поэтому возможность time-travel по-прежнему доступна с теми же значениями.
Как использовать: