🌲 Зачем вообще нужны движки MergeTree Family
🔥 Главная мысль
Многие думают так:
есть MergeTree, значит этого уже достаточно для всех задач.
Но на практике обычный MergeTree — это только база.
А дальше начинаются разные сценарии:
• где-то нужно убирать дубли • где-то суммировать данные при merge • где-то хранить агрегатные состояния • где-то моделировать обновления • где-то прореживать метрики
Именно для этого и существует MergeTree Family.
Если сказать совсем просто:
MergeTree Family — это набор движков, которые по-разному ведут себя во время merge.
🟢 Плюсы:
• можно выбрать движок под конкретную задачу • часть логики переносится ближе к хранению данных • можно уменьшать объём данных уже на уровне merge • удобнее строить витрины, дедупликацию и предагрегацию
Пример плюса: если тебе нужно хранить события без дублей, обычный MergeTree сам это не решит. А ReplacingMergeTree уже подходит для такого сценария.
🔴 Минусы:
• легко выбрать не тот движок • поведение merge у разных движков отличается • без понимания FINAL можно получить неожиданный результат • часть логики происходит не сразу, а только во время фоновых слияний
Пример минуса: человек создаёт ReplacingMergeTree, вставляет дубли, делает SELECT и удивляется, почему дубликаты ещё видны. А потому что merge ещё не произошёл, и без FINAL результат может быть ещё “сырой”.
🧪 Живые примеры
Какие движки чаще всего всплывают в MergeTree Family:
• SummingMergeTree • AggregatingMergeTree • ReplacingMergeTree • CollapsingMergeTree • VersionedCollapsingMergeTree • GraphiteMergeTree
Что делает каждый из них по-простому:
- SummingMergeTree
Во время merge суммирует числовые поля и оставляет одну строку по ключу.
Когда полезен: если нужно хранить уже частично агрегированные метрики.
- AggregatingMergeTree
Похож на SummingMergeTree, но умеет работать не только с суммой, а с агрегатными состояниями.
Когда полезен: если строишь сложные предагрегированные витрины.
- ReplacingMergeTree
Оставляет одну строку с последней версией или самую последнюю вставленную строку.
Когда полезен: если нужна дедупликация и модель “обновления через перевставку”.
- CollapsingMergeTree
Схлопывает пары строк по специальному sign.
Когда полезен: если приложение само управляет “отменой” старых значений.
- VersionedCollapsingMergeTree
Развивает идею CollapsingMergeTree и добавляет версию.
Когда полезен: если обновления приходят параллельно и нужна более аккуратная модель схлопывания.
- GraphiteMergeTree
Нужен для rollup и прореживания метрик.
Когда полезен: если работаешь с временными рядами и историческими метриками.
🏗 Архитектурная мысль
В больших компаниях MergeTree Family — это способ не тащить всю логику только в ETL или BI.
Часть задач можно решить уже на уровне движка хранения:
• дедупликацию • частичную агрегацию • хранение агрегатных состояний • моделирование обновлений • rollup метрик
Что это даёт:
• меньше лишней логики вне ClickHouse • проще некоторые витрины • меньше объём данных при чтении • логика становится ближе к данным
⚠️ Риски:
• выбрать движок “по названию”, а не по задаче • забыть, что merge происходит в фоне • не учитывать, что SELECT без FINAL может показать “сырое” состояние • путать дедупликацию, агрегацию и схлопывание как разные сценарии
Самая частая ошибка — думать, что все движки MergeTree Family отличаются только названием.
На практике они отличаются тем, что делают с данными во время merge.
✅ Вывод
MergeTree Family — это не набор редких экзотических движков 🌲
Это способ выбрать правильную механику хранения под задачу:
• суммировать • агрегировать • схлопывать • дедуплицировать • прореживать метрики
Если обычный MergeTree — это база, то MergeTree Family — это уже архитектурный выбор под конкретный сценарий ⚙️