Открыть сервис

MergeTree

MergeTree — это семейство движков (движков таблиц) для хранения данных в колоночной системе управления базами данных ClickHouse, разработанной компанией «Яндекс» (ныне развивается как open-source проект). MergeTree является основным и наиболее универсальным типом таблиц в ClickHouse, предназначенным для высокопроизводительной аналитической обработки (OLAP) больших объёмов данных. Ключевые особенности движка: поддержка партиционирования, сортировки данных по первичному ключу, автоматического слияния фрагментов (merge) и репликации.

История и происхождение

MergeTree был разработан в 2012–2013 годах в рамках внутреннего проекта «Яндекс.Метрика» для обработки огромных массивов веб-аналитики. Основная цель — обеспечить быструю вставку данных (до миллионов строк в секунду) и эффективную агрегацию по времени и другим ключевым измерениям. Название «MergeTree» происходит от алгоритма слияния (merge) отсортированных частей данных (partitions), который лежит в основе движка.

Первая публичная версия ClickHouse с MergeTree вышла в 2016 году. С тех пор движок стал основой для многих OLAP-решений в России и мире, включая сервисы «Яндекса» (Метрика, Директ, Поиск), а также сторонние компании (например, Cloudflare, Uber, eBay).

Архитектура и принцип работы

Основные компоненты

  • Таблица MergeTree: логическая структура, которая хранит данные в виде набора партиций (partition) и частей (parts). Каждая часть — это отсортированный по ключу сортировки фрагмент данных, хранящийся в виде колоночных файлов (например, .bin, .mrk).
  • Партиционирование: данные разбиваются на логические разделы по заданному выражению (обычно по дате или месяцу). Это позволяет быстро удалять старые данные и ускорять запросы с фильтрацией по времени.
  • Ключ сортировки (ORDER BY): определяет порядок строк внутри каждой части. Данные физически хранятся отсортированными, что ускоряет операции диапазонного сканирования и агрегации.
  • Первичный ключ (PRIMARY KEY): задаёт уникальные значения для индексации. В MergeTree первичный ключ не обязательно уникален, он используется для построения разреженного индекса (sparse index), который позволяет быстро находить нужные блоки данных.
  • Индексы: помимо первичного ключа, поддерживаются вторичные индексы (например, bloom filter, minmax, set) для ускорения фильтрации по неключевым колонкам.

Процесс вставки и слияния

  1. Вставка: новые строки записываются в виде небольшой отсортированной части (part) на диск. Каждая вставка создаёт отдельную часть, что может приводить к фрагментации.
  2. Слияние (merge): фоновый процесс автоматически объединяет мелкие части в более крупные, отсортированные по ключу. Слияние выполняется в фоне, не блокируя запись и чтение. Это позволяет поддерживать эффективность запросов и снижать количество файлов.
  3. Удаление и обновление: MergeTree поддерживает мутации (ALTER UPDATE/DELETE), которые выполняются асинхронно, создавая новые версии частей. Старые части удаляются после завершения мутации.

Классификация движков семейства MergeTree

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

  • MergeTree: базовый движок без репликации и дедупликации. Подходит для тестовых или однократных нагрузок.
  • ReplicatedMergeTree: добавляет репликацию данных между несколькими серверами ClickHouse с использованием ZooKeeper (или ClickHouse Keeper). Обеспечивает отказоустойчивость и согласованность.
  • SummingMergeTree: автоматически суммирует числовые значения при слиянии, агрегируя строки с одинаковым ключом сортировки. Полезен для кумулятивных метрик (например, счётчики).
  • AggregatingMergeTree: хранит промежуточные состояния агрегатных функций (например, uniqState, avgState). Позволяет выполнять инкрементальные агрегации.
  • CollapsingMergeTree: использует специальный столбец Sign для обработки изменений (логическое удаление или обновление). Строки с Sign = 1 — вставка, с Sign = -1 — отмена.
  • VersionedCollapsingMergeTree: расширение CollapsingMergeTree, поддерживающее версионность для корректной обработки изменений.
  • GraphiteMergeTree: оптимизирован для хранения данных мониторинга (Graphite), поддерживает автоматическое усреднение и агрегацию по времени.
  • ReplacingMergeTree: удаляет дубликаты строк с одинаковым ключом сортировки при слиянии, оставляя только последнюю версию (по времени или версии).

Применение

MergeTree используется в задачах, требующих высокой производительности аналитических запросов на больших объёмах данных (терабайты и петабайты). Основные сценарии:

  • Веб-аналитика: обработка логов посещений, кликов, событий. Например, «Яндекс.Метрика» обрабатывает миллиарды событий в день.
  • Мониторинг и телеметрия: хранение метрик серверов, приложений, сетевого трафика.
  • Финансовые системы: анализ транзакций, расчёт агрегатов по времени.
  • Рекламные платформы: обработка кликов, показов, конверсий.
  • Научные данные: анализ временных рядов (например, погодные данные, данные датчиков).

Преимущества и недостатки

Преимущества

  • Высокая скорость вставки: до 10–100 миллионов строк в секунду на одном сервере (зависит от конфигурации).
  • Эффективная агрегация: благодаря сортировке и колоночному хранению, запросы с GROUP BY и фильтрацией по ключу выполняются быстро.
  • Масштабируемость: поддержка репликации и шардирования (через распределённые таблицы).
  • Сжатие данных: колоночное хранение позволяет использовать эффективные алгоритмы сжатия (LZ4, ZSTD, Delta), снижая объём хранилища в 2–10 раз.
  • Гибкость: широкий выбор движков под разные сценарии (суммирование, дедупликация, версионность).

Недостатки

  • Ограниченная поддержка транзакций: нет ACID-транзакций в классическом понимании (только асинхронные мутации).
  • Сложность настройки: требуется понимание партиционирования, ключей сортировки и индексов для оптимальной производительности.
  • Фрагментация: при частых мелких вставках может расти количество частей, что замедляет слияние и запросы. Требуется настройка фоновых процессов.
  • Не подходит для OLTP: не поддерживает точечные обновления и удаления с низкой задержкой.

Интересные факты

  • MergeTree использует разреженный индекс (sparse index), который хранит не каждую строку, а диапазоны (гранулы). Это позволяет индексу помещаться в оперативной памяти даже для таблиц с миллиардами строк.
  • В ClickHouse существует материализованные представления (Materialized View), которые могут быть построены поверх MergeTree для автоматического агрегирования данных.
  • Движок ReplicatedMergeTree использует алгоритм Quorum для обеспечения согласованности при репликации.
  • MergeTree поддерживает TTL (Time To Live) — автоматическое удаление устаревших данных на основе времени.

Критика

Основные критические замечания касаются сложности администрирования и ограниченной поддержки сложных запросов (например, JOIN с большими таблицами). Также отмечается, что для небольших объёмов данных (менее 100 ГБ) MergeTree может быть избыточен, и проще использовать традиционные реляционные СУБД (PostgreSQL, MySQL). Однако в контексте OLAP-нагрузок MergeTree остаётся одним из самых производительных решений.

Источники

  • Официальная документация ClickHouse: «MergeTree Table Engine» (clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree)
  • Статья «Как мы делали ClickHouse» (блог «Яндекса», 2016)
  • Книга «ClickHouse: The Definitive Guide» (O'Reilly, 2020)
  • Исходный код ClickHouse на GitHub (github.com/ClickHouse/ClickHouse)

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →