Почему ClickHouse такой быстрый?
На производительность базы данных влияет множество факторов, помимо формата хранения данных. Далее мы подробно объясним, что делает ClickHouse таким быстрым, особенно по сравнению с другими колоночными базами данных.
С архитектурной точки зрения базы данных состоят (как минимум) из слоя хранения и слоя обработки запросов. Слой хранения отвечает за сохранение, загрузку и поддержание данных таблиц, а слой обработки запросов выполняет пользовательские запросы. По сравнению с другими базами данных ClickHouse реализует инновации в обоих слоях, что обеспечивает чрезвычайно быстрые операции вставки и запросы SELECT.
Уровень хранения: одновременные вставки изолированы друг от друга
В ClickHouse каждая таблица состоит из нескольких «частей таблицы» (table parts). Часть создаётся каждый раз, когда пользователь вставляет данные в таблицу (оператор INSERT). Запрос всегда обрабатывает все части таблицы, которые существуют на момент его запуска.
Чтобы избежать накопления слишком большого количества частей, ClickHouse в фоновом режиме выполняет операцию слияния, которая непрерывно объединяет несколько меньших частей в одну более крупную.
Такой подход имеет несколько преимуществ: всю обработку данных можно перенести во фоновые слияния частей, сохраняя операции записи данных лёгкими и высокоэффективными. Отдельные вставки являются «локальными» в том смысле, что им не нужно обновлять глобальные, то есть относящиеся ко всей таблице структуры данных. В результате нескольким одновременным вставкам не требуется взаимная синхронизация или синхронизация с уже существующими данными таблицы, поэтому вставки могут выполняться почти на скорости операций дискового ввода-вывода.
🤿 Подробно об этом рассказано в разделе Формат на диске веб-версии нашей статьи VLDB 2024.
Уровень хранения: одновременные операции INSERT и SELECT изолированы
Операции INSERT полностью изолированы от запросов SELECT, а слияние вставленных частей данных выполняется в фоновом режиме и не влияет на конкурентные запросы.
🤿 Подробнее об этом — в разделе Уровень хранения веб-версии нашей статьи VLDB 2024.
Уровень хранения: вычисления во время слияния
В отличие от других баз данных, ClickHouse обеспечивает лёгкую и эффективную запись данных, выполняя все дополнительные преобразования данных во фоновом процессе merge. Примеры таких преобразований:
-
Replacing merges — сохраняют только самую последнюю версию строки во входных частях и отбрасывают все остальные версии этой строки. Replacing merges можно рассматривать как операцию очистки во время слияния.
-
Aggregating merges — объединяют промежуточные состояния агрегации во входной части в новое агрегированное состояние. Хотя это может показаться сложным для понимания, по сути это просто реализация инкрементной агрегации.
-
TTL (time-to-live) merges — сжимают, перемещают или удаляют строки на основе определённых временных правил.
Цель этих преобразований — перенести работу (вычисления) с момента выполнения пользовательских запросов на момент слияния. Это важно по двум причинам:
С одной стороны, пользовательские запросы могут стать значительно быстрее, иногда более чем в 1000 раз, если они могут использовать «преобразованные» данные, например заранее агрегированные.
С другой стороны, основная часть времени выполнения слияний расходуется на загрузку входных частей и сохранение выходной части. Дополнительные затраты на преобразование данных во время слияния обычно не оказывают существенного влияния на время выполнения слияний. Вся эта «магия» полностью прозрачна и не влияет на результат запросов (если не считать производительность).
🤿 Подробно об этом рассказывается в разделе Преобразование данных во время merge веб-версии нашего доклада на конференции VLDB 2024.
Уровень хранения: прореживание данных
На практике многие запросы повторяются, то есть выполняются без изменений или лишь с незначительными модификациями (например, с другими значениями параметров) через регулярные интервалы времени. Повторное выполнение одних и тех же или похожих запросов позволяет добавить индексы или реорганизовать данные так, чтобы часто выполняемые запросы получали к ним более быстрый доступ. Такой подход также известен как «прореживание данных» (data pruning), и ClickHouse предоставляет для этого три техники:
-
Индексы первичного ключа, которые задают порядок сортировки данных таблицы. Правильно выбранный первичный ключ позволяет вычислять фильтры (как выражения WHERE в приведённом выше запросе) с помощью быстрых двоичных поисков вместо полных сканирований столбцов. Говоря более технически, время выполнения сканирований становится логарифмическим, а не линейным по размеру данных.
-
Проекции таблиц — это альтернативные внутренние версии таблицы, хранящие те же данные, но отсортированные по другому первичному ключу. Проекции могут быть полезны, когда существует более одного часто используемого условия фильтрации.
-
Пропускающие индексы, которые встраивают дополнительную статистику по данным в столбцы, например минимальное и максимальное значение столбца, множество уникальных значений и т.д. Пропускающие индексы ортогональны первичным ключам и проекциям таблиц и, в зависимости от распределения данных в столбце, могут существенно ускорить вычисление фильтров.
Все три техники нацелены на то, чтобы пропускать как можно больше строк при полном сканировании столбцов, поскольку самый быстрый способ прочитать данные — это вовсе их не читать.
🤿 Подробнее об этом в разделе Data Pruning веб-версии нашей статьи VLDB 2024.
Уровень хранения: сжатие данных
Помимо этого, уровень хранения ClickHouse дополнительно (и по желанию) может сжимать исходные данные таблиц, используя различные кодеки.
Колонночные хранилища особенно хорошо подходят для такого сжатия, поскольку значения одного типа и с одинаковым распределением данных располагаются рядом.
Пользователи могут задать, что столбцы сжимаются с помощью различных универсальных алгоритмов сжатия (таких как ZSTD) или специализированных кодеков, например Gorilla и FPC для значений с плавающей запятой, Delta и GCD для целочисленных значений или даже AES в качестве шифрующего кодека.
Сжатие данных не только уменьшает объём данных в таблицах базы данных, но во многих случаях также улучшает производительность запросов, поскольку локальные диски и сетевой ввод-вывод часто ограничены низкой пропускной способностью.
🤿 Подробный разбор см. в разделе Формат на диске веб-версии нашей статьи для VLDB 2024.
Передовой слой обработки запросов
Наконец, ClickHouse использует векторизованный слой обработки запросов, который максимально распараллеливает их выполнение, чтобы задействовать все ресурсы и обеспечить максимальную скорость и эффективность.
«Векторизация» означает, что операторы плана запроса передают промежуточные результирующие строки пакетами, а не по одной строке. Это приводит к более эффективному использованию кешей CPU и позволяет операторам применять SIMD-инструкции для обработки нескольких значений одновременно. Фактически, многие операторы доступны в нескольких версиях — по одной на каждое поколение набора SIMD-инструкций. ClickHouse автоматически выберет самую новую и быструю версию в зависимости от возможностей аппаратного обеспечения, на котором он запущен.
Современные системы имеют десятки ядер CPU. Чтобы задействовать все ядра, ClickHouse разворачивает план запроса в несколько параллельных потоков обработки, обычно по одному на каждое ядро. Каждый поток обрабатывает непересекающийся диапазон данных таблицы. Таким образом, производительность базы данных масштабируется «вертикально» с увеличением числа доступных ядер.
Если одного узла становится недостаточно, чтобы хранить все данные таблицы, можно добавить дополнительные узлы и сформировать кластер. Таблицы могут быть разделены («шардированы») и распределены по узлам. ClickHouse будет выполнять запросы на всех узлах, где хранятся данные таблицы, тем самым масштабируясь «горизонтально» с увеличением числа доступных узлов.
🤿 Подробный разбор этой темы приведен в разделе Query Processing Layer веб-версии нашей статьи VLDB 2024 года.
Скрупулёзное внимание к деталям
"ClickHouse — это безумная система: у вас есть 20 версий хеш-таблицы. У вас есть все эти удивительные вещи, тогда как в большинстве систем есть одна хеш-таблица ... ClickHouse показывает невероятную производительность, потому что в нём есть все эти специализированные компоненты" Andy Pavlo, профессор баз данных в CMU
То, что отличает ClickHouse от других систем, — это скрупулёзное внимание к низкоуровневой оптимизации. Создать базу данных, которая просто работает, — одно, но спроектировать её так, чтобы обеспечивать высокую скорость для разных типов запросов, структур данных, распределений и конфигураций индексов, — это уже область, где раскрывается искусство "freak system".
Хеш-таблицы. Возьмём хеш-таблицу как пример. Хеш-таблицы — ключевые структуры данных, которые используются в операциях JOIN и агрегациях. Программисту нужно учитывать следующие конструкторские решения:
- Какую хеш-функцию выбрать,
- Как разрешать коллизии: открытая адресация или цепочки,
- Какой использовать формат представления в памяти: один массив для ключей и значений или отдельные массивы?
- Коэффициент заполнения: когда и как изменять размер? Как перемещать значения при изменении размера?
- Удаления: должна ли хеш-таблица позволять удалять (выселять) элементы?
Стандартная хеш-таблица, предоставляемая сторонней библиотекой, будет корректно работать функционально, но не будет быстрой. Высокая производительность требует тщательного тестирования и бенчмаркинга.
Реализация хеш-таблицы в ClickHouse выбирает один из 30+ предварительно скомпилированных вариантов хеш-таблиц на основе специфики запроса и данных.
Алгоритмы. То же относится и к алгоритмам. Например, при сортировке нужно учитывать:
- Что будет сортироваться: числа, кортежи, строки или структуры?
- Находятся ли данные в оперативной памяти (RAM)?
- Требуется ли стабильная сортировка?
- Нужно отсортировать все данные или достаточно частичной сортировки?
Алгоритмы, использующие особенности данных, часто работают лучше, чем их обобщённые аналоги. Если характеристики данных заранее неизвестны, система может попробовать несколько реализаций и во время выполнения выбрать ту, которая работает лучше всего. В качестве примера см. статью о том, как реализована декомпрессия LZ4 в ClickHouse.
🤿 Подробно об этом читайте в разделе Holistic Performance Optimization веб-версии нашей статьи VLDB 2024.
Статья на VLDB 2024
В августе 2024 года наша первая исследовательская статья была принята и опубликована в материалах конференции VLDB. VLDB — это международная конференция по очень большим базам данных, которая широко считается одной из ведущих в области управления данными. Среди сотен заявок доля принятых докладов на VLDB обычно составляет около 20%.
Вы можете прочитать PDF-версию статьи или нашу веб-версию, в которой дано краткое описание самых интересных архитектурных решений и компонентов системы ClickHouse, делающих его таким быстрым.
Алексей Миловидов, наш CTO и создатель ClickHouse, представил статью (слайды здесь), после чего последовала сессия вопросов и ответов (время на неё очень быстро закончилось!). Запись доклада доступна здесь: