Перейти к основному содержанию

Что такое слияние частей в ClickHouse?


ClickHouse работает быстро не только при выполнении запросов, но и при вставке данных благодаря своему уровню хранения, который устроен схожим образом с LSM-деревьями: ① Вставки (в таблицы семейства движков MergeTree) создают отсортированные неизменяемые части данных. ② Вся обработка данных переносится в фоновые слияния частей. Это делает запись данных малозатратной и высокоэффективной. Чтобы контролировать количество частей в таблице и реализовать описанное в пункте ② выше, ClickHouse непрерывно объединяет (в пределах каждой партиции) меньшие части в более крупные в фоновом режиме, пока их сжатый размер не достигнет примерно ~150 GB. Следующая диаграмма схематично показывает этот фоновый процесс слияния:
merge level части увеличивается на единицу с каждым очередным слиянием. Уровень 0 означает, что часть новая и еще не была объединена. Части, объединенные в более крупные, помечаются как неактивные и затем удаляются через настраиваемый промежуток времени (по умолчанию 8 минут). Со временем это образует дерево слитых частей. Отсюда и название таблицы MergeTree.

Мониторинг слияний

В примере что такое части таблицы мы показали, что ClickHouse отслеживает все части таблицы в системной таблице parts. Мы использовали следующий запрос, чтобы получить уровень слияния и число хранимых строк для каждой активной части таблицы из примера:
SELECT
    name,
    level,
    rows
FROM system.parts
WHERE (database = 'uk') AND (`table` = 'uk_price_paid_simple') AND active
ORDER BY name ASC;
Результат ранее приведённого запроса показывает, что в таблице из примера было четыре активные части, каждая из которых была создана в результате одного слияния изначально вставленных частей:
   ┌─name────────┬─level─┬────rows─┐
1. │ all_0_5_1   │     1 │ 6368414 │
2. │ all_12_17_1 │     1 │ 6442494 │
3. │ all_18_23_1 │     1 │ 5977762 │
4. │ all_6_11_1  │     1 │ 6459763 │
   └─────────────┴───────┴─────────┘
После запуска запроса теперь видно, что четыре части уже слились в одну итоговую часть (при условии, что в таблицу больше не выполняются вставки):
   ┌─name───────┬─level─┬─────rows─┐
1. │ all_0_23_2 │     2 │ 25248433 │
   └────────────┴───────┴──────────┘
В ClickHouse 24.10 во встроенные панели мониторинга была добавлена новая панель мониторинга слияний. Она доступна как в OSS, так и в Cloud через HTTP-обработчик /merges и позволяет визуализировать все слияния частей для таблицы из нашего примера:
На записи панели мониторинга выше показан весь процесс — от первоначальных вставок данных до итогового слияния в одну часть: ① Количество активных частей. ② Слияния частей, визуально представленные прямоугольниками (их размер отражает размер части). Усиление записи.

Параллельные слияния

Один сервер ClickHouse использует несколько фоновых потоков слияния для выполнения параллельных слияний частей:
Каждый поток слияния выполняет цикл: ① Определяет, какие части сливать следующими, и загружает их в память. ② Объединяет части в памяти в одну более крупную часть. ③ Записывает слитую часть на диск. Вернитесь к ① Обратите внимание: увеличение числа ядер CPU и объема оперативной памяти позволяет повысить пропускную способность фоновых слияний.

Слияния с оптимизацией по памяти

ClickHouse не обязательно загружает в память все части, подлежащие слиянию, сразу, как показано в предыдущем примере. В зависимости от нескольких факторов и для снижения потребления памяти (ценой скорости слияния) так называемое вертикальное слияние загружает и сливает части фрагментами блоков, а не все сразу.

Механика слияния

Диаграмма ниже показывает, как один фоновый поток слияния в ClickHouse объединяет части (по умолчанию без вертикального слияния):
Слияние частей выполняется в несколько этапов: ① Декомпрессия и загрузка: сжатые бинарные файлы столбцов из частей, подлежащих слиянию, распаковываются и загружаются в память. ② Слияние: Данные сливаются в более крупные файлы столбцов. ③ Индексация: Для слитых файлов столбцов создаётся новый разреженный первичный индекс. ④ Сжатие и хранение: Новые файлы столбцов и индекс сжимаются и сохраняются в новом каталоге, который представляет слитую часть данных. Дополнительные метаданные в частях данных, такие как вторичные индексы пропуска данных, статистика столбцов, контрольные суммы и min-max-индексы, также пересоздаются на основе слитых файлов столбцов. Для простоты мы опустили эти детали. Механика этапа ② зависит от конкретного движка MergeTree, поскольку разные движки выполняют слияние по-разному. Например, устаревшие строки могут агрегироваться или заменяться. Как уже упоминалось, такой подход переносит всю обработку данных в фоновые слияния, обеспечивая сверхбыстрые вставки за счёт того, что операции записи остаются лёгкими и эффективными. Далее мы кратко рассмотрим механику слияния в конкретных движках семейства MergeTree.

Стандартные слияния

На схеме ниже показано, как выполняется слияние частей в стандартной таблице MergeTree:
DDL-оператор на схеме выше создаёт таблицу MergeTree с ключом сортировки (town, street), то есть данные на диске сортируются по этим столбцам, и на их основе создаётся разреженный первичный индекс. ① Распакованные предварительно отсортированные столбцы таблицы ② объединяются с сохранением глобального порядка сортировки, заданного ключом сортировки таблицы, ③ создаётся новый разреженный первичный индекс, а ④ объединённые файлы столбцов и индекс сжимаются и сохраняются на диске как новая часть данных.

Слияния в ReplacingMergeTree

Слияния частей в таблице ReplacingMergeTree работают аналогично стандартным слияниям, но сохраняется только самая новая версия каждой строки, а более старые версии отбрасываются:
DDL-оператор на диаграмме выше создаёт таблицу ReplacingMergeTree с ключом сортировки (town, street, id), то есть данные на диске сортируются по этим столбцам, а соответствующим образом строится разреженный первичный индекс. На этапе ② слияние происходит так же, как и в стандартной таблице MergeTree: объединяются распакованные, предварительно отсортированные столбцы с сохранением глобального порядка сортировки. Однако ReplacingMergeTree удаляет дублирующиеся строки с одинаковым ключом сортировки, сохраняя только самую новую строку по временной метке создания части, в которой она находится.

Суммирующие слияния

Числовые данные автоматически суммируются при слиянии частей таблицы SummingMergeTree:
DDL-оператор на схеме выше определяет таблицу SummingMergeTree, где town используется как ключ сортировки. Это означает, что данные на диске сортируются по этому столбцу и на его основе создаётся разреженный первичный индекс. На этапе слияния ② ClickHouse заменяет все строки с одинаковым ключом сортировки одной строкой, суммируя значения числовых столбцов.

Слияния с агрегацией

Пример таблицы SummingMergeTree, приведённый выше, — это специализированный вариант таблицы AggregatingMergeTree, который позволяет выполнять автоматическое инкрементальное преобразование данных, применяя любую из 90+ функций агрегации при слиянии частей:
DDL-оператор на диаграмме выше создаёт таблицу AggregatingMergeTree, в которой town используется как ключ сортировки, что гарантирует упорядочивание данных по этому столбцу на диске и создание соответствующего разреженного первичного индекса. Во время ② слияния ClickHouse заменяет все строки с одинаковым ключом сортировки одной строкой, в которой хранятся Промежуточные состояния агрегации (например, sum и count для avg()). Эти состояния обеспечивают точные результаты благодаря инкрементальным фоновым слияниям.
Последнее изменение 10 июня 2026 г.