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

Уровень слияния
части увеличивается на один с каждым дополнительным слиянием. Уровень 0
означает, что часть новая и еще не была слита. Части, которые были слиты в большие части, помечаются как неактивные и в конечном итоге удаляются после настраиваемого времени (по умолчанию 8 минут). С течением времени это создает дерево слитых частей. Поэтому название слияние деревьев таблицы.
Мониторинг слияний
В примере, что такое части таблицы мы показали, что ClickHouse отслеживает все части таблицы в системной таблице parts. Мы использовали следующий запрос, чтобы получить уровень слияния и количество хранимых строк для каждой активной части примерной таблицы:
Выполнение запрос сейчас показывает, что четыре части слились в одну финальную часть (при условии, что в таблицу нет новых вставок):
Выполнение запрос сейчас показывает, что четыре части слились в одну финальную часть (при условии, что в таблицу нет новых вставок):
В ClickHouse 24.10 был добавлен новый приборная панель слияний в встроенные панели мониторинга. Доступная как в OSS, так и в Cloud через HTTP-обработчик /merges
, мы можем использовать ее для визуализации всех слияний частей для нашей примерной таблицы:

Записанная выше панель захватывает весь процесс, начиная с первоначальных вставок данных и заканчивая финальным слиянием в одну часть:
① Количество активных частей.
② Слияния частей, визуально представлены в виде коробок (размер отражает размер части).
Одновременные слияния
Один сервер ClickHouse использует несколько фоновых потоков слияния для выполнения одновременных слияний частей:

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

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

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

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

DDL-запрос в диаграмме выше определяет таблицу SummingMergeTree
с town
в качестве ключа сортировки, что означает, что данные на диске отсортированы по этой колонке, и соответствующий разреженный первичный индекс создается.
На этапе ② слияния ClickHouse заменяет все строки с одинаковым ключом сортировки одной строкой, суммируя значения числовых колонок.
Аггрегирующие слияния
Пример таблицы SummingMergeTree
выше является специализированным вариантом таблицы AggregatingMergeTree, позволяющим автоматическую инкрементную трансформацию данных путем применения любой из 90+ агрегатных функций во время слияний частей:

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