Базы данных

Предварительная агрегация потоковых данных в ClickHouse

Сравнение подходов к предварительной агрегации высокопроизводительных потоковых данных в ClickHouse: AggregatingMergeTree + материализованные представления vs ReplacingMergeTree для идемпотентности.

4 ответа 1 просмотр

Как подойти к предварительной агрегации высокопроизводительных потоковых данных в ClickHouse в продакшене? Стоит ли использовать AggregatingMergeTree + материализованные представления вместо запроса к сырым таблицам или полагаться больше на ReplacingMergeTree для идемпотентности?

Предварительная агрегация высокопроизводительных потоковых данных в ClickHouse в продакшене требует комплексного подхода с использованием AggregatingMergeTree в сочетании с материализованными представлениями, которые автоматически обновляют агрегатные состояния при вставке новых данных. Этот подход значительно сокращает количество строк в таблице и ускоряет чтение агрегированных данных по сравнению с прямой обработкой сырых данных или использованием ReplacingMergeTree исключительно для идемпотентности. Для обеспечения идемпотентности лучше использовать комбинацию подходов, где AggregatingMergeTree отвечает за агрегацию, а ReplacingMergeTree или FINAL оператор - за удаление дубликатов на этапе слияния.


Содержание


Введение в агрегацию потоковых данных в ClickHouse

ClickHouse является одной из наиболее эффективных систем для обработки потоковых данных благодаря своей колоночной архитектуре и специализированным движкам таблиц. При работе с высокопроизводительными потоковыми данными в продакшене возникает ключевая проблема: как эффективно агрегировать данные в реальном времени без потери производительности и при сохранении целостности данных.

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

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


AggregatingMergeTree: принципы работы и применение в продакшене

AggregatingMergeTree — это специализированный движок таблиц в ClickHouse, предназначенный для хранения агрегатных состояний. В отличие от обычных таблиц, которые хранят отдельные строки, AggregatingMergeTree хранит частичные результаты агрегации, которые могут быть объединены в ходе слияния частей таблицы.

Ключевая особенность AggregatingMergeTree заключается в поддержке специальных агрегатных функций, которые работают с состоянием: sumState, uniqState, anyState, minState, maxState и другие. Эти функции позволяют накапливать агрегатные состояния при вставке данных, а затем в запросе SELECT с помощью функций finalizeAggregation получать итоговые результаты.

sql
CREATE TABLE metrics_aggregated (
 date Date,
 user_id String,
 metric_sum AggregateFunction(sum, UInt64),
 metric_count AggregateFunction(count, UInt64),
 metric_avg AggregateFunction(avg, Float64)
) ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, user_id);

В продакшене AggregatingMergeTree особенно эффективен при работе с потоковыми данными, так как позволяет на порядок сократить количество строк в таблице. При вставке данных в таблицу AggregatingMergeTree можно использовать параметр optimize_on_insert = 0, чтобы не группировать данные на этапе вставки, а делить агрегирование на этапе слияния частей таблицы.

Преимущества AggregatingMergeTree для потоковых данных:

  • Существенное сокращение объема хранимых данных
  • Ускорение выполнения агрегирующих запросов
  • Возможность инкрементального обновления агрегатов
  • Эффективная работа с высокими скоростями вставки

Недостатки:

  • Требует дополнительной логики для работы с агрегатными состояниями
  • Не обеспечивает идемпотентность на уровне вставки
  • Требует понимания принципов работы агрегатных функций

Материализованные представления для предварительной агрегации данных

Материализованные представления (Materialized Views) в ClickHouse являются мощным инструментом для предварительной агрегации потоковых данных. Они автоматически выполняют указанный SELECT-запрос при вставке новых данных в исходную таблицу и сохраняют результаты в целевую таблицу.

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

sql
CREATE TABLE raw_metrics (
 timestamp DateTime,
 user_id String,
 metric_value Float64
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, user_id);

CREATE MATERIALIZED VIEW daily_metrics_mv TO daily_metrics
AS SELECT
 toDate(timestamp) as date,
 user_id,
 sum(metric_value) as total_value,
 count() as count,
 avg(metric_value) as avg_value
FROM raw_metrics
GROUP BY date, user_id;

Внутренний движок для оконных представлений по умолчанию — AggregatingMergeTree, но для обычных материализованных представлений можно задать любой движок, например SummingMergeTree, если нужна агрегация по ключу.

Для периодической агрегации можно использовать refreshable materialized view, которая выполняет запрос по расписанию и сохраняет результат в целевой таблице. Это полезно, когда нужно выполнять агрегацию не только по новым данным, но и по историческим данным с определенной периодичностью.

Преимущества материализованных представлений:

  • Автоматическое обновление при вставке новых данных
  • Отделение логики агрегации от бизнес-логики приложения
  • Возможность использования различных движков для целевых таблиц
  • Эффективное инкрементальное обновление

Недостатки:

  • Требуют дополнительного места для хранения агрегированных данных
  • Могут усложнить схему базы данных
  • Требуют дополнительного обслуживания и мониторинга

ReplacingMergeTree для обеспечения идемпотентности

ReplacingMergeTree — это движок таблиц в ClickHouse, предназначенный для удаления дубликатов строк. В отличие от AggregatingMergeTree, который фокусируется на агрегации данных, ReplacingMergeTree фокусируется на обеспечении уникальности данных на уровне слияния.

Ключевая особенность ReplacingMergeTree заключается в том, что он удаляет дубликаты только во время слияния частей таблицы, а не на уровне вставки. Это означает, что при непосредственной вставке дубликаты могут временно присутствовать в таблице, и только при последующем OPTIMIZE TABLE или автоматическом слиянии они будут удалены.

Для идемпотентности можно использовать ReplacingMergeTree с оператором FINAL или ручными оптимизациями OPTIMIZE TABLE … FINAL CLEANUP. Оператор FINAL позволяет получить данные после удаления дубликатов без фактического выполнения оптимизации.

sql
CREATE TABLE events_unique (
 timestamp DateTime,
 event_id String,
 event_data String,
 version UInt64
) ENGINE = ReplacingMergeTree(version)
PARTITION BY toYYYYMM(timestamp)
ORDER BY (event_id, timestamp);

-- Для получения уникальных событий с учетом версий:
SELECT * FROM events_unique FINAL;

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

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

  • Гарантия удаления дубликатов на уровне слияния
  • Поддержка версионности данных
  • Простота использования для обеспечения уникальности
  • Эффективная работа с большими объемами данных

Недостатки:

  • Не выполняет агрегацию данных
  • Не гарантирует отсутствие дубликатов до слияния
  • Требует указания порядка сортировки для определения дубликатов
  • Может создавать ложное впечатление идемпотентности на уровне вставки

Сравнительный анализ подходов: AggregatingMergeTree + MV vs ReplacingMergeTree

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

AggregatingMergeTree + Материализованные представления

Этот подход является наиболее предпочтительным для предварительной агрегации потоковых данных в продакшене:

  1. Производительность: AggregatingMergeTree позволяет на порядок сократить количество строк в таблице, что значительно ускоряет чтение агрегированных данных.

  2. Инкрементальность: Материализованные представления автоматически обновляют агрегатные состояния при вставке новых данных, что позволяет эффективно обрабатывать поток данных без перерасчета всей истории.

  3. Гибкость: Поддержка различных агрегатных функций позволяет реализовывать сложные сценарии агрегации, включая суммы, средние значения, уникальные значения и другие метрики.

  4. Масштабируемость: Подход хорошо масштабируется на большие объемы данных и высокие скорости вставки, характерные для потоковых систем.

Недостатки этого подхода:

  • Требует дополнительного места для хранения как исходных, так и агрегированных данных
  • Не обеспечивает полной идемпотентности на уровне вставки
  • Требует более сложной схемы базы данных

ReplacingMergeTree

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

  1. Идемпотентность: Обеспечивает удаление дубликатов на уровне слияния, что полезно для гарантии уникальности событий.

  2. Простота: Легко интегрируется в существующие схемы без значительных изменений.

  3. Версионность: Поддерживает версионность данных, что полезно для аудита и восстановления.

Однако этот подход не подходит для предварительной агрегации по следующим причинам:

  • Не выполняет агрегацию данных, а только удаляет дубликаты
  • Не гарантирует отсутствие дубликатов до слияния
  • Требует указания порядка сортировки для определения дубликатов
  • Может создавать ложное впечатление идемпотентности на уровне вставки

Комбинированный подход

Наиболее эффективным решением для продакшена является комбинированный подход, где:

  1. AggregatingMergeTree отвечает за агрегацию данных и хранение агрегатных состояний
  2. Материализованные представления обеспечивают автоматическое обновление агрегатов при вставке новых данных
  3. ReplacingMergeTree или FINAL оператор используются для обеспечения идемпотентности на уровне слияния
sql
-- Комбинированный подход
CREATE TABLE raw_events (
 timestamp DateTime,
 user_id String,
 event_type String,
 metric_value Float64,
 event_id String
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, user_id, event_id);

CREATE MATERIALIZED VIEW events_aggregated_mv TO events_aggregated
AS SELECT
 toDate(timestamp) as date,
 user_id,
 event_type,
 sum(metric_value) as total_value,
 count() as count,
 uniq(event_id) as unique_events
FROM raw_events
GROUP BY date, user_id, event_type;

CREATE TABLE events_aggregated (
 date Date,
 user_id String,
 event_type String,
 total_value AggregateFunction(sum, Float64),
 count AggregateFunction(count, UInt64),
 unique_events AggregateFunction(uniq, String)
) ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, user_id, event_type);

CREATE MATERIALIZED VIEW events_unique_mv TO events_unique
AS SELECT *
FROM events_aggregated;

CREATE TABLE events_unique (
 date Date,
 user_id String,
 event_type String,
 total_value AggregateFunction(sum, Float64),
 count AggregateFunction(count, UInt64),
 unique_events AggregateFunction(uniq, String)
) ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, user_id, event_type);

Практические рекомендации и лучшие практики для продакшена

При реализации предварительной агрегации потоковых данных в ClickHouse в продакшене следует придерживаться следующих рекомендаций:

1. Стратегия разделения данных

Разделяйте данные по времени и ключевым атрибутам для эффективной работы с потоковыми данными:

sql
-- Пример оптимальной стратегии разделения
CREATE TABLE user_metrics (
 event_time DateTime,
 user_id String,
 metric_name String,
 metric_value Float64,
 session_id String
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, user_id, metric_name);

2. Оптимизация параметров AggregatingMergeTree

Используйте параметр optimize_on_insert для управления поведением на этапе вставки:

sql
CREATE TABLE aggregated_metrics (
 date Date,
 user_id String,
 metric_sum AggregateFunction(sum, Float64),
 metric_count AggregateFunction(count, UInt64)
) ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, user_id)
SETTINGS optimize_on_insert = 0; -- Не группировать на вставке

3. Управление жизненным циклом данных

Реализуйте стратегию управления жизненным циклом данных для агрегированных таблиц:

sql
-- Автоматическая очистка старых данных
ALTER TABLE aggregated_metrics
 DROP PARTITION '2023-01';

-- Архивирование редко используемых данных
CREATE TABLE archived_metrics ENGINE = MergeTree()
AS SELECT * FROM aggregated_metrics
WHERE date < today() - INTERVAL '30' DAY;

4. Мониторинг и производительность

Внедрите мониторинг производительности для идентификации узких мест:

sql
-- Мониторинг производительности вставки
SELECT *
FROM system.query_log
WHERE type = 'QueryStart'
AND database = 'your_database'
AND table = 'aggregated_metrics'
ORDER BY event_time DESC
LIMIT 100;

-- Анализ размера таблиц
SELECT
 database,
 table,
 sum(rows) as total_rows,
 sum(data_compressed_bytes) as total_size
FROM system.parts
WHERE active = 1
GROUP BY database, table;

5. Обработка ошибок и восстановление

Реализуйте механизмы обработки ошибок и восстановления данных:

sql
-- Резервное копирование
BACKUP TABLE aggregated_metrics TO 'backups/aggregated_metrics';

-- Восстановление
RESTORE TABLE aggregated_metrics FROM 'backups/aggregated_metrics';

-- Обработка дубликатов
OPTIMIZE TABLE aggregated_metrics FINAL CLEANUP;

6. Масштабирование и распределение

Для обработки больших объемов данных используйте распределенную архитектуру:

sql
-- Создание 分布式表
CREATE TABLE distributed_aggregated_metrics ON CLUSTER cluster_name
AS SELECT *
FROM local_aggregated_metrics
ENGINE = Distributed(cluster_name, default, local_aggregated_metrics, user_id);

7. Безопасность и доступ

Реализуйте политики безопасности для защиты агрегированных данных:

sql
-- Ограничение доступа к агрегированным данным
GRANT SELECT ON aggregated_metrics TO analytics_role;
GRANT INSERT ON raw_events TO ingestion_role;

-- Маскировка чувствительных данных
CREATE MATERIALIZED VIEW masked_events_mv TO masked_events
AS SELECT
 event_time,
 user_id,
 metric_name,
 round(metric_value, 2) as metric_value
FROM raw_events;

8. Тестирование и валидация

Разработайте стратегии тестирования для проверки корректности агрегации:

sql
-- Тестирование агрегации
SELECT
 date,
 user_id,
 finalizeAggregation(metric_sum) as total,
 finalizeAggregation(metric_count) as count,
 total / count as average
FROM aggregated_metrics
GROUP BY date, user_id;

-- Сравнение с сырыми данными
SELECT
 date,
 user_id,
 sum(metric_value) as raw_total,
 count() as raw_count,
 (SELECT finalizeAggregation(metric_sum) FROM aggregated_metrics WHERE date = t.date AND user_id = t.user_id) as agg_total,
 (SELECT finalizeAggregation(metric_count) FROM aggregated_metrics WHERE date = t.date AND user_id = t.user_id) as agg_count
FROM raw_events t
GROUP BY date, user_id;

Следуя этим рекомендациям, можно создать надежную и эффективную систему для предварительной агрегации высокопроизводительных потоковых данных в ClickHouse в продакшене.


Источники

  1. AggregatingMergeTree Documentation — Официальная документация движка AggregatingMergeTree для агрегации потоковых данных: https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/aggregatingmergetree

  2. ReplacingMergeTree Documentation — Документация движка ReplacingMergeTree для обеспечения идемпотентности: https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replacingmergetree

  3. Materialized Views Documentation — Информация о материализованных представлениях для предварительной агрегации данных: https://clickhouse.com/docs/ru/sql-reference/statements/create/view


Заключение

Для предварительной агрегации высокопроизводительных потоковых данных в ClickHouse в продакшене рекомендуется использовать комбинированный подход с AggregatingMergeTree в сочетании с материализованными представлениями. Этот подход позволяет эффективно сокращать количество строк в таблице, ускорять чтение агрегированных данных и обеспечивать автоматическое обновление агрегатов при вставке новых данных.

ReplacingMergeTree может быть полезен для обеспечения идемпотентности на уровне слияния, но не подходит для предварительной агрегации данных, так как он только удаляет дубликаты, а не выполняет агрегацию. Для обеспечения идемпотентности в комбинированном подходе можно использовать FINAL оператор или дополнительные механизмы контроля дубликатов.

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

ClickHouse / Система управления базами данных

AggregatingMergeTree в сочетании с материализованными представлениями является оптимальным решением для потоковых данных в продакшене. Этот подход позволяет хранить агрегатные состояния в таблице и автоматически обновлять их при вставке новых данных. При использовании можно сохранять состояния агрегатных функций (sumState, uniqState) и применять GROUP BY в запросе SELECT, либо использовать функцию initializeAggregation с параметром optimize_on_insert = 0. Это решение уменьшает количество строк в таблице на порядок и значительно ускоряет чтение агрегированных данных.

ClickHouse / Система управления базами данных

ReplacingMergeTree обеспечивает удаление дубликатов только во время слияния частей таблицы и не гарантирует их отсутствие в реальном времени. Для обеспечения идемпотентности можно использовать ReplacingMergeTree с оператором FINAL или ручными оптимизациями OPTIMIZE TABLE … FINAL CLEANUP. Однако для предварительной агрегации потоковых данных этот подход не является оптимальным, так как он не выполняет агрегацию, а только удаляет дубликаты на основе указанного порядка сортировки.

К

Материализованные представления являются предпочтительным подходом для предварительной агрегации высокопроизводительных потоковых данных в ClickHouse в продакшене. Они агрегируют только новые вставки, поэтому при постоянном потоке данных работают как триггер на вставку. Для периодической агрегации можно использовать обновляемые материализованные представления (refreshable materialized view), которые выполняют запрос по расписанию и сохраняют результат в целевой таблице. Внутренний движок для оконных представлений по умолчанию – AggregatingMergeTree, но для обычных материализованных представлений можно задать любой движок, например SummingMergeTree, если нужна агрегация по ключу.

Авторы
Источники
ClickHouse / Система управления базами данных
Система управления базами данных
Проверено модерацией
НейроОтветы
Модерация