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

Слияние частей

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


ClickHouse быстрый не только для запросов, но и для вставок, благодаря его слою хранения, который работает аналогично LSM деревьям:

① Вставки (в таблицы от движка MergeTree) создают отсортированные, неизменяемые части данных.

② Все операции обработки данных выполняются в фоновом слиянии частей.

Это делает записи данных легковесными и высокоэффективными.

Чтобы контролировать количество частей в таблице и реализовать ② выше, ClickHouse постоянно сливает (по разделу) меньшие части в более крупные в фоновом режиме, пока они не достигнут сжатого размера примерно ~150 ГБ.

Следующий диаграмма иллюстрирует этот процесс фонового слияния:


Уровень слияния части увеличивается на единицу с каждым последующим слиянием. Уровень 0 означает, что часть новая и еще не была объединена. Части, которые были объединены в более крупные, помечаются как неактивные и в конечном итоге удаляются после настраиваемого времени (по умолчанию 8 минут). Со временем это создает дерево объединенных частей. Поэтому название дерево слияния.

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

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

[Запуск] (https://sql.clickhouse.com/?query=U0VMRUNUCiAgICBuYW1lLAogICAgbGV2ZWwsCiAgICByb3dzCkZST00gc3lzdGVtLnBhcnRzCldIRVJFIChkYXRhYmFzZSA9ICd1aycpIEFORCAoYHRhYmxlYCA9ICd1a19wcmljZV9wYWlkX3NpbXBsZScpIEFORCBhY3RpdmUKT1JERVIgQlkgbmFtZSBBU0M7&run_query=true&tab=results) запроса сейчас показывает, что четыре части слились в одну финальную часть (если в таблицу не было внесено никаких дополнительных вставок):

В ClickHouse 24.10 была добавлена новая панель мониторинга слияний в встроенные панели мониторинга. Доступная как в OSS, так и в Cloud через HTTP обработчик /merges, мы можем использовать ее для визуализации всех слияний частей для нашей примерной таблицы:


Записанная панель мониторинга выше фиксирует весь процесс, от начальных вставок данных до окончательного слияния в одну часть:

① Количество активных частей.

② Слияния частей, визуально представлены с помощью коробок (размер отражает размер части).

Увеличение записи.

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

Один сервер ClickHouse использует несколько фоновых потоков слияния для выполнения параллельных слияний частей:


Каждый поток слияния выполняет цикл:

① Решить, какие части объединить следующими, и загрузить эти части в память.

② Объединить части в памяти в более крупную часть.

③ Записать объединенную часть на диск.

Идем к ①

Обратите внимание, что увеличение количества ядер CPU и объема ОЗУ позволяет увеличить пропускную способность фонового слияния.

Оптимизированные по памяти слияния

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

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

Диаграмма ниже иллюстрирует, как один фоновый поток слияния в ClickHouse объединяет части (по умолчанию, без вертикального слияния):


Слияние частей выполняется в несколько этапов:

① Декомпрессия и загрузка: Сжатые бинарные файлы столбцов из частей, которые должны быть объединены, декомпрессируются и загружаются в память.

② Слияние: Данные объединяются в более крупные файлы столбцов.

③ Индексация: Новый разреженный первичный индекс генерируется для объединенных файлов столбцов.

④ Сжатие и хранение: Новые файлы столбцов и индекс сжимаются и сохраняются в новой директории, представляющей объединенную часть данных.

Дополнительные метаданные в частях данных, такие как вторичные индексы пропуска данных, статистика столбцов, контрольные суммы и минимальные-максимальные индексы, также воссоздаются на основе объединенных файлов столбцов. Мы опустили эти детали для простоты.

Механика шага ② зависит от конкретного движка MergeTree, используемого, поскольку разные движки обрабатывают слияние по-разному. Например, строки могут агрегироваться или заменяться, если устарели. Как уже упоминалось, этот подход переносит всю обработку данных на фоновое слияние, позволяя сверхбыстрые вставки, сохраняя операции записи легковесными и эффективными.

Далее мы кратко опишем механику слияния конкретных движков в семействе MergeTree.

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

Диаграмма ниже иллюстрирует, как части в стандартной MergeTree таблице объединяются:


DDL оператор на диаграмме выше создает таблицу MergeTree с ключом сортировки (город, улица), что означает, что данные на диске отсортированы по этим столбцам, и соответственно генерируется разреженный первичный индекс.

Декомпрессированные, предварительно отсортированные ① столбцы таблицы объединяются ②, сохраняя глобальный порядок сортировки таблицы, определяемый ключом сортировки таблицы, ③ генерируется новый разреженный первичный индекс, и ④ объединенные файлы столбцов и индекс сжимаются и сохраняются как новая часть данных на диске.

Заменяющие слияния

Слияние частей в таблице ReplacingMergeTree работает аналогично стандартным слияниям, но сохраняется только самая последняя версия каждой строки, а более старые версии отбрасываются:


DDL оператор на диаграмме выше создает таблицу ReplacingMergeTree с ключом сортировки (город, улица, id), что означает, что данные на диске отсортированы по этим столбцам, с соответствующим разреженным первичным индексом.

Слияние ② работает аналогично стандартной таблице MergeTree, объединяя декомпрессированные, предварительно отсортированные столбцы, сохраняя глобальный порядок сортировки.

Однако ReplacingMergeTree удаляет дублирующиеся строки с одинаковым ключом сортировки, оставляя только самую последнюю строку на основе временной метки создания содержащей ее части.


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

Числовые данные автоматически суммируются во время слияний частей из таблицы SummingMergeTree:


DDL оператор на диаграмме выше определяет таблицу SummingMergeTree с городом в качестве ключа сортировки, что означает, что данные на диске отсортированы по этому столбцу и соответственно генерируется разреженный первичный индекс.

На этапе ② слияния ClickHouse заменяет все строки с тем же ключом сортировки одной строкой, суммируя значения числовых столбцов.

Агрегирующие слияния

Пример таблицы SummingMergeTree выше является специализированным вариантом таблицы AggregatingMergeTree, позволяющим автоматическое инкрементальное преобразование данных с применением любой из 90+ агрегатных функций во время слияний частей:


DDL оператор на диаграмме выше создает таблицу AggregatingMergeTree с городом в качестве ключа сортировки, обеспечивая, что данные упорядочены по этому столбцу на диске и соответствующий разреженный первичный индекс генерируется.

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