Как именно формат, сортировка, сжатие и интерфейс передачи данных в ClickHouse влияют на скорость операций загрузки: бенчмаркинговое сравнение от разработчиков колоночной СУБД.
В каком формате данные быстрее всего вставляются в ClickHouse
Продолжая недавний разговор про вставку данных в ClickHouse, сегодня рассмотрим, ключевые факторы, которые особенно сильно влияют на скорость загрузки данных в это колоночное хранилище. Бенчмаркинговое исследование, проведенное разработчиками ClickHouse, показывает, что наибольший вклад в скорость загрузки вносят формат данных, алгоритм их сжатия и интерфейс передачи.
ClickHouse поддерживает более 70 форматов данных, которые можно разделить на три основные категории:
- Текстовые (CSV, TSV и JSON);
- двоичные колоночно-ориентированные (Native, Parquet, Arrow)
- двоичные строко-ориентированные (RowBinary, Protobuf, Avro).
Исследования показали, что наиболее эффективным является бинарный формат Native, который разработан для высокопроизводительной обработки данных с низкой задержкой. Будучи по-настоящему колоночным, этот формат не преобразует столбцы в строки: данные в этом формате данные записываются и считываются блоками. Для каждого блока поочередно записываются количество строк, количество столбцов, имена и типы столбцов, а также части столбцов в блоке. Его колоночная структура близко соответствует формату таблицы семейства MergeTree, что снижает необходимость в дополнительных преобразованиях на стороне сервера. Этот формат используется в собственном интерфейсе для взаимодействия между серверами, а также в клиенте командной строки и клиенте C++ для ClickHouse. Формат Native имеет высокие коэффициенты сжатия для эффективной сетевой передачи и минимальные накладные расходы на обработку на стороне сервера. Можно использовать этот формат для быстрой генерации дампов, которые будут читаться только самим ClickHouse.
Ожидаемо, что сложные структуры данных, такие как массивы, JSON/BSON-документы, обрабатываются намного медленнее. Поэтому данные, загружаемые в ClickHouse в форматах JSON/BSON, вставляются дольше. Это подтверждает бенчмаркинговый тест последовательной вставки 1000 пакетов по 10000 строк каждый, проведенный разработчиками ClickHouse.
Впрочем, на скорость вставки также влияет и сжатие данных, что мы рассмотрим далее.
Сжатие данных
ClickHouse изначально поддерживает множество кодеков и алгоритмов сжатия:
- ZSTD эффективен для большинства типов и распределений данных. Именно этот алгоритм сжатия по умолчанию используется в облачной версии ClickHouse Cloud с предустановленным значением 1. Он разархивируется последовательно и может быть параллелизованным.
- Кодеки Delta хорошо работают с монотонными последовательностями или небольшими изменениями в последовательных значениях. Если монотонное увеличение является равномерным, например, поля DateTime, стоит попробовать DoubleDelta.
- Алгоритм LZ4, по сравнению с ZSTD, предлагает более быстрое декомпрессирование и требует меньше ресурсов ЦП. Этот алгоритма используется по умолчанию в открытой версии ClickHouse.
- T64 может быть эффективным для разреженных данных или когда диапазон в блоке мал, но не подходит для случайных чисел;
- Gorilla может быть эффективным для данных с плавающей точкой, особенно тех, которые представляют показания измерений, т.е. случайные всплески.
Настроить метод сжатия можно для каждой отдельной колонки таблицы в запросе CREATE TABLE. Однако, сжатие поддерживается только для следующих табличных движков:
- семейство MergeTree (поддерживает кодеки сжатия колонок и выбор метода сжатия по умолчанию через настройки compression);
- семейство Log (по умолчанию использует LZ4 и поддерживает кодеки сжатия колонок);
- Set (только сжатие по умолчанию);
- Join (только сжатие по умолчанию).
Предварительная сортировка данных еще больше повышает эффективность сжатия, сокращая их объем, а также исключает этап сортировки на стороне самого ClickHouse. Однако, предварительная сортировка на клиенте рекомендуется, когда данные уже почти упорядочены и на клиентской стороне достаточно вычислительных ресурсов, поскольку ClickHouse часто может сортировать данные быстрее, чем клиентское приложение. Поскольку на практике несколько клиентов работают одновременно, например, когда сотни или тысячи агентов отправляют метрики в хранилище, при параллельных вставках становится сложно отслеживать использование ресурсов на стороне сервера. Поэтому в таком случае лучше выполнять предварительную обработку данных на клиенте. При вставке данных одним клиентом можно переложить это на сторону сервера.
Интерфейс передачи данных
Наконец, интерфейс передачи данных в Clickhouse тоже существенно влияет на скорость их вставки. Clickhouse-client использует исключительно собственный интерфейс, придерживаясь основного принципа разгрузки работы на клиента для максимизации эффективности сервера. Вместо отправки необработанных данных, например, TSV или JSON, он сначала анализирует и преобразует входные данные в эффективный формат Native, обеспечивая оптимальное сжатие для сетевой передачи и минимальную обработку на стороне сервера. Поскольку формат Native и таблицы MergeTree имеют одну и ту же колоночную структуру, прием упрощается и сокращает накладные расходы на преобразование данных на стороне сервера. Native — единственный формат, поддерживаемый собственным интерфейсом. Кроме того, собственный интерфейс поддерживает поблочное сжатие и декомпрессию данных. Clickhouse-client всегда сжимает данные с помощью алгоритма LZ4 по умолчанию или ZSTD и передает блоки данных в потоковом режиме, оптимизируя эффективность передачи. Материализованные вычисления и вычисления значений по умолчанию (DEFAULT) реализует только clickhouse-client. Таким образом, собственный интерфейс взаимодействия с Clickhouse позволяет использовать передовые методы оптимизации вставок, обеспечивая эффективную транспортировку и минимальную обработку на стороне сервера.
В отличие от собственного интерфейса, HTTP-интерфейс поддерживает отправку данных в любом из поддерживаемых форматов ввода, а не только в собственном. Для этого интерфейс HTTP поддерживает предложение FORMAT, но не предложение COMPRESSION. Также он не определяет сжатие автоматически. Чтобы включить сжатие для вставок по HTTP-интерфейсу, необходимо использовать сжатие HTTP с заголовком Content-Encoding. При этом перед передачей данных сжимается весь пакет.
Хотя интерфейс HTTP также поддерживает отправку данных в формате Native, в нем отсутствуют расширенные механизмы связи, необходимые клиентам для обработки значений MATERIALIZED и DEFAULT, когда DDL целевой таблицы зависит от определенного формата, например JSON. В отличие от собственного интерфейса, который позволяет извлекать DDL таблицы и дает серверу указание пропустить вычисление этих значений, интерфейс HTTP не поддерживает такие взаимодействия. Поэтому клиенты, использующие HTTP, не всегда могут автоматически преобразовывать входные данные в формат Native. Таким образом, интерфейс HTTP обеспечивает большую гибкость, чем собственный интерфейс для выбора форматов ввода, отправляемых на сервер, поддерживает дополнительные параметры сжатия помимо LZ4 и ZSTD, но работает более медленно.
Помимо CLI-инструментов, клиенты для разных языков программирования предоставляют различные уровни поддержки для каждого интерфейса. Например, собственный интерфейс в настоящее время поддерживается только клиентами C++ и Go (запланирована поддержка Rust). Все основные языковые клиенты, кроме C++, поддерживают интерфейс HTTP.
Ни один из клиентов не выполняет автоматическую предварительную сортировку данных перед передачей их на сервер. Это должно быть реализовано вручную, что потенциально может быть менее эффективно, чем процесс сортировки на стороне сервера. Возможности клиента различаются в зависимости от типичных шаблонов рабочей нагрузки приложений. В частности, на C++ и Go обычно пишутся приложения для высокопроизводительных вставок, а на JavaScript — приложения с большим объемом запросов.
Освойте ClickHouse на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники
- https://clickhouse.com/blog/clickhouse-input-format-matchup-which-is-fastest-most-efficient
- https://fastformats.clickhouse.com/
- https://clickhouse.com/docs/integrations/data-formats/binary-native
- https://clickhouse.com/docs/ru/data-compression/compression-in-clickhouse
- https://clickhouse.com/blog/optimize-clickhouse-codecs-compression-schema