ClickStack - Materialized Views
Введение
ClickStack может использовать Incremental Materialized Views (IMV) для ускорения визуализаций, которые опираются на ресурсоёмкие агрегирующие запросы, например вычисление средней длительности запроса по минутам во времени. Эта функция может существенно повысить производительность запросов и особенно полезна для крупных развертываний — порядка 10 ТБ в день и выше, — при этом обеспечивая масштабирование до объёмов порядка PB данных в день. Incremental materialized views находятся в стадии Beta и должны использоваться с осторожностью.
Оповещения также могут выигрывать от использования materialized views и будут автоматически их задействовать. Это может уменьшить вычислительные затраты на выполнение большого количества оповещений, особенно с учётом того, что они обычно запускаются очень часто. Сокращение времени выполнения может быть полезно как с точки зрения отзывчивости, так и с точки зрения потребления ресурсов.
Что такое incremental materialized views
Incremental materialized views позволяют перенести стоимость вычислений с времени выполнения запроса на время вставки, что приводит к значительно более быстрым запросам SELECT.
В отличие от транзакционных баз данных, таких как Postgres, materialized view в ClickHouse не является сохранённым снимком данных. Вместо этого она действует как триггер, который выполняет запрос над блоками данных по мере их вставки в исходную таблицу. Результат этого запроса записывается в отдельную целевую таблицу. По мере вставки дополнительных данных новые частичные результаты добавляются и сливаются в целевую таблицу. Объединённый результат эквивалентен выполнению агрегации над всем исходным набором данных.
Основная причина использования materialized views состоит в том, что данные, записываемые в целевую таблицу, представляют собой результат агрегации, фильтрации или трансформации. В ClickStack они используются исключительно для агрегаций. Эти результаты, как правило, значительно меньше исходных необработанных данных и часто представляют собой состояния частичных агрегаций. В сочетании с простотой выполнения запросов к предагрегированной целевой таблице это приводит к существенно меньшей задержке выполнения запросов по сравнению с выполнением тех же вычислений по «сырым» данным во время запроса.
Materialized views в ClickHouse обновляются непрерывно по мере поступления данных в исходную таблицу, ведя себя скорее как всегда актуальные индексы. Это отличается от многих других баз данных, где materialized views являются статическими снимками, которые необходимо периодически обновлять, аналогично ClickHouse Refreshable Materialized Views.

Incremental materialized views вычисляют только изменения представления по мере поступления новых данных, перенося вычисления на время вставки. Поскольку ClickHouse сильно оптимизирован для ингестии, дополнительная стоимость поддержания представления для каждого вставляемого блока мала по сравнению с экономией, достигаемой при выполнении запросов. Стоимость вычисления агрегации распределяется по операциям вставки, а не оплачивается многократно при каждом чтении. Запрос к предагрегированным результатам, таким образом, значительно менее затратен, чем их повторное вычисление, что снижает операционные затраты и обеспечивает практически работу в реальном времени для последующих визуализаций, даже в петабайтных масштабах.
Эта модель принципиально отличается от систем, которые пересчитывают представления целиком при каждом обновлении или полагаются на плановые обновления по расписанию. Для более подробного объяснения того, как работают materialized views и как их создавать, обратитесь к упомянутому выше руководству.
Каждая materialized view вносит дополнительные накладные расходы во время вставки, поэтому их следует использовать избирательно.
Создавайте представления только для наиболее часто используемых дашбордов и визуализаций. Ограничьте использование числом менее 20 представлений, пока функция находится в бета-версии. Ожидается, что этот порог будет увеличен в будущих релизах.
Одна materialized view может вычислять несколько метрик для разных группировок, например минимальную, максимальную и p95 длительность по имени сервиса в одноминутных интервалах. Это позволяет одному представлению обслуживать множество визуализаций, а не только одну. Поэтому консолидация метрик в общих представлениях важна для максимизации ценности каждого представления и обеспечения его повторного использования в разных дашбордах и рабочих процессах.
Прежде чем двигаться дальше, рекомендуется подробнее ознакомиться с materialized views в ClickHouse. См. наше руководство по Incremental materialized views для получения дополнительных подробностей.
Выбор визуализаций для ускорения
Прежде чем создавать какие-либо объекты materialized view, важно понять, какие визуализации вы хотите ускорить и какие рабочие процессы наиболее критичны для ваших пользователей.
В ClickStack объекты materialized view предназначены для ускорения визуализаций с ресурсоёмкими агрегациями, то есть запросов, которые вычисляют одну или несколько метрик во времени. Примеры включают среднюю длительность запроса в минуту, количество запросов по сервисам или уровень ошибок во времени. Объект materialized view всегда должен содержать агрегацию и группировку по времени, так как он предназначен для обслуживания визуализаций временных рядов.
В целом рекомендуется следующее:
Определите наиболее значимые визуализации
Лучшие кандидаты для ускорения обычно относятся к одной из следующих категорий:
- Визуализации на дашбордах, которые часто обновляются и постоянно отображаются, например, высокоуровневые мониторинговые дашборды на настенных экранах.
- Диагностические процессы, используемые в runbook'ах, где к определённым графикам неоднократно обращаются во время реагирования на инциденты и которым нужно быстро возвращать результаты.
- Ключевые сценарии работы в HyperDX, включая:
- Представления гистограмм на странице поиска.
- Визуализации, используемые в преднастроенных дашбордах, таких как представления APM, Services или Kubernetes.
Эти визуализации часто выполняются многократно разными пользователями и для различных диапазонов времени, что делает их идеальными кандидатами для переноса вычислений с времени выполнения запроса на время вставки данных.
Соотносите выгоду с затратами на вставку данных
Materialized views добавляют дополнительную работу во время вставки данных, поэтому их следует создавать выборочно и осознанно. Не каждая визуализация выигрывает от предагрегации, и ускорение редко используемых графиков, как правило, не окупает накладные расходы. Общее число materialized views следует держать ниже максимального значения в 20.
Перед выводом в production всегда проверяйте накладные расходы на ресурсы, которые создают materialized views, в особенности использование CPU, дисковый I/O и merge activity. Каждая materialized view увеличивает объем работы при вставке и добавляет новые части, поэтому важно убедиться, что операции слияния успевают обрабатывать вставки и количество частей остается стабильным. За этим можно следить через system tables и встроенный обсервабилити-дэшборд в open-source ClickHouse или с помощью встроенных метрик и дашбордов мониторинга в ClickHouse Cloud. См. раздел Too many parts с рекомендациями по диагностике и снижению избыточного количества частей.
После того как вы определили наиболее важные визуализации, следующим шагом будет консолидация.
Объединение визуализаций в общие представления
Все materialized views в ClickStack должны группировать данные по временным интервалам с использованием таких функций, как toStartOfMinute. Однако многие визуализации также используют дополнительные ключи группировки, такие как имя сервиса, имя спана или код статуса. Когда несколько визуализаций используют одинаковые измерения для группировки, их часто можно обслуживать одной materialized view.
Например (для трейсов):
- Средняя длительность по имени сервиса во времени —
SELECT avg(Duration), toStartOfMinute(Timestamp) as time, ServiceName FROM otel_traces GROUP BY ServiceName, time - Количество запросов по имени сервиса во времени —
SELECT count() count, toStartOfMinute(Timestamp) as time, ServiceName FROM otel_traces GROUP BY ServiceName, time - Средняя длительность по коду статуса во времени —
SELECT avg(Duration), toStartOfMinute(Timestamp) as time, StatusCode FROM otel_traces GROUP BY StatusCode, time - Количество запросов по коду статуса во времени —
SELECT count() count, toStartOfMinute(Timestamp) as time, StatusCode FROM otel_traces GROUP BY StatusCode, time
Вместо того чтобы создавать отдельные materialized views для каждого запроса и графика, вы можете объединить их в одну materialized view с агрегацией по имени сервиса и коду статуса. Эта единая materialized view может вычислять несколько метрик, таких как count, средняя длительность, максимальная длительность, а также перцентили, которые затем можно переиспользовать в нескольких визуализациях. Пример запроса, объединяющего приведённые выше, показан ниже:
Объединение представлений таким образом снижает накладные расходы на вставку данных, ограничивает общее количество materialized view, уменьшает проблемы с количеством частей и упрощает дальнейшее обслуживание.
На данном этапе сосредоточьтесь на запросах, лежащих в основе визуализаций, которые вы хотите ускорить. В следующем разделе вы увидите пример, демонстрирующий, как несколько агрегирующих запросов могут быть объединены в одну materialized view.
Создание materialized view
После того как вы определили визуализацию или набор визуализаций, которые хотите ускорить, следующим шагом будет определение базовых запросов. На практике это означает анализ конфигурации визуализации и просмотр сгенерированного SQL, с особым вниманием к используемым метрикам агрегации и применённым функциям.

Если для компонента в HyperDX недоступна панель отладки, пользователи могут проверить консоль браузера, где логируются все запросы.
После того как вы соберёте все необходимые запросы, вам следует ознакомиться с функциями агрегатных состояний (aggregate state functions) в ClickHouse. Materialized views опираются на эти функции, чтобы перенести вычисления с момента выполнения запроса на момент вставки данных. Вместо хранения окончательных агрегированных значений materialized view вычисляет и хранит промежуточные состояния агрегации, которые затем объединяются и финализируются во время выполнения запроса. Они, как правило, будут значительно меньше исходной таблицы. Эти состояния имеют отдельные типы данных и должны быть явно представлены в схеме целевой таблицы.
Для справки ClickHouse предоставляет подробный обзор и примеры функций агрегатных состояний, а также табличного движка, используемого для их хранения — AggregatingMergeTree — в документации:
Вы можете увидеть пример использования AggregatingMergeTree и Aggregate functions в видео ниже:
Настоятельно рекомендуется ознакомиться с этими понятиями, прежде чем двигаться дальше.
Пример materialized view
Рассмотрим следующий исходный запрос, который вычисляет среднюю и максимальную длительность, количество событий и перцентили для каждой минуты, сгруппированных по имени сервиса и коду статуса:
Чтобы ускорить выполнение этого запроса, создайте таблицу otel_traces_1m, которая хранит соответствующие состояния агрегации:
Затем materialized view otel_traces_1m_mv вычисляет эти состояния и записывает их по мере вставки новых данных:
Этот materialized view состоит из двух частей:
- Целевая таблица, которая определяет схему и типы агрегатных состояний, используемых для хранения промежуточных результатов. Движок AggregatingMergeTree необходим для того, чтобы эти состояния корректно сливались в фоновом режиме.
- Запрос materialized view выполняется автоматически при вставке. По сравнению с исходным запросом он использует state-функции, такие как
avgStateиquantilesState, вместо финальных агрегирующих функций.
Результатом является компактная таблица, которая хранит агрегатные состояния с поминутной детализацией для каждого имени сервиса и кода статуса. Ее размер предсказуемо растет со временем и кардинальностью, и после фоновых слияний она дает тот же результат, что и выполнение исходной агрегации по сырым данным. Запросы к этой таблице значительно дешевле, чем агрегация напрямую из исходной таблицы трассировок, что обеспечивает быструю и стабильную производительность визуализаций при масштабировании.
Использование materialized view в ClickStack
После создания materialized view в ClickHouse их необходимо зарегистрировать в ClickStack, чтобы визуализации, дашборды и оповещения могли автоматически их использовать.
Регистрация materialized view для использования
Materialized view следует зарегистрировать для source в HyperDX, который соответствует исходной таблице, на основе которой была создана эта view.
Изменение source
Перейдите к соответствующему source в HyperDX и откройте диалоговое окно Edit configuration. Пролистайте до раздела materialized view.

Добавление materialized view
Выберите Add materialized view, затем укажите базу данных и целевую таблицу, которые лежат в основе materialized view.

Выбор метрик
В большинстве случаев столбцы с временной меткой, измерениями и метриками определяются автоматически. Если этого не произошло, укажите их вручную.
Для метрик необходимо сопоставить:
- исходное имя столбца, например
Duration, с - соответствующим агрегированным столбцом в materialized view, например
avg__Duration
Для измерений укажите все столбцы, кроме временной метки, по которым выполняется группировка во view.

Выбор временной гранулярности
Выберите time granularity для materialized view, например одну минуту.

Указание минимальной даты
Укажите минимальную дату, для которой materialized view содержит данные. Она представляет собой самую раннюю временную метку, доступную во view, и обычно соответствует времени её создания при условии непрерывной ингестии.
Materialized view не заполняются задним числом автоматически при их создании, поэтому они будут содержать только строки, сформированные из данных, вставленных после создания. Полное руководство по заполнению materialized view задним числом (backfilling) можно найти в разделе "Заполнение данных задним числом."

Если точное время начала неизвестно, вы можете определить его, выполнив запрос, возвращающий минимальную временную метку из целевой таблицы, например:
После регистрации materialized view она автоматически используется ClickStack при каждом запросе, который может быть ею обслужен, без необходимости вносить изменения в дашборды, визуализации или оповещения. ClickStack оценивает каждый запрос во время выполнения и определяет, может ли быть применена materialized view.
Проверка ускорения в дашбордах и визуализациях
Важно помнить, что incremental materialized views содержат только данные, вставленные после создания представления. Они не заполняются ретроспективно автоматически, что делает их легковесными и недорогими в обслуживании. По этой причине пользователям необходимо явно указывать корректный диапазон времени для представления при его регистрации.
ClickStack будет использовать materialized view только в том случае, если его минимальная метка времени меньше или равна началу диапазона времени запроса, что гарантирует наличие всех необходимых данных в представлении. Хотя запросы внутренне разбиваются на подсчёты по временным интервалам, materialized views применяются либо ко всему запросу целиком, либо не применяются вовсе. В будущих улучшениях может появиться возможность избирательно использовать представления для подходящих подзапросов.
ClickStack предоставляет наглядные визуальные индикаторы, позволяющие проверить, используется ли materialized view.
- Проверьте статус оптимизации. При просмотре дашборда или визуализации найдите значок молнии или
Accelerated:
- Зелёная молния означает, что запрос ускорен с помощью materialized view.
- Оранжевая молния означает, что запрос выполняется по исходной таблице.

- Изучите детали оптимизации. Нажмите на значок молнии, чтобы открыть панель с деталями, в которой отображаются:
- Активный materialized view: представление, выбранное для запроса, включая оценочное количество строк.
- Пропущенные materialized views: совместимые представления, которые не были выбраны, с указанием их примерных объёмов сканирования.
- Несовместимые materialized views: представления, которые не удалось использовать, и конкретная причина этого.
- Разберитесь с распространёнными причинами несовместимости. Materialized view может не использоваться, если:
- Диапазон времени запроса начинается раньше минимальной метки времени представления.
- Детализация визуализации не является кратной детализации представления.
- Агрегирующая функция, запрошенная в запросе, отсутствует в представлении.
- Запрос использует пользовательские выражения подсчёта, такие как
count(if(...)), которые не могут быть выведены из агрегирующих состояний представления.
Эти индикаторы упрощают проверку того, ускорена ли визуализация, понимание причин выбора конкретного представления и диагностику причин, по которым представление не было использовано.
Как выбираются materialized view для визуализаций
Когда выполняется визуализация, у ClickStack может быть несколько доступных кандидатов, включая базовую таблицу и несколько materialized view. Чтобы обеспечить оптимальную производительность, ClickStack автоматически оценивает и выбирает наиболее эффективный вариант, используя механизм ClickHouse EXPLAIN ESTIMATE.
Процесс выбора следует четко определенной последовательности:
-
Проверка совместимости
Сначала ClickStack определяет, может ли materialized view быть использован для запроса, проверяя:- Покрытие по времени: временной диапазон запроса должен полностью попадать в диапазон доступных данных materialized view.
- Гранулярность: временной интервал (time bucket) визуализации должен быть равен или больше (крупнее), чем гранулярность представления.
- Агрегации: запрашиваемые метрики должны присутствовать в представлении и вычисляться из его агрегированных состояний.
-
Преобразование запроса
Для совместимых представлений ClickStack переписывает запрос так, чтобы он обращался к таблице materialized view:- Функции агрегирования сопоставляются с соответствующими материализованными столбцами.
- К агрегированным состояниям применяются комбинаторы
-Merge. - Временная агрегация (time bucketing) корректируется для выравнивания с гранулярностью представления.
-
Выбор наилучшего кандидата
Если доступно несколько совместимых materialized view, ClickStack выполняет запросEXPLAIN ESTIMATEдля каждого кандидата и сравнивает оценочное количество строк и гранул, подлежащих сканированию. Выбирается представление с наименьшей оценочной стоимостью сканирования. -
Прозрачный откат
Если ни один materialized view не совместим, ClickStack автоматически откатывается к выполнению запроса к исходной таблице.
Такой подход стабильно минимизирует объем сканируемых данных и обеспечивает предсказуемую низкую задержку без необходимости изменять определения визуализаций.
Materialized view по-прежнему могут быть использованы, даже когда визуализации включают фильтры, поисковые ограничения или временную агрегацию, при условии, что все требуемые размерности присутствуют в представлении. Это позволяет представлениям ускорять дашборды, гистограммы и фильтрованные графики без необходимости изменять определения визуализаций.
Пример выбора materialized view
Рассмотрим две materialized view, построенные на одном и том же источнике трассировок:
otel_traces_1m, сгруппированная по минуте,ServiceNameиStatusCodeotel_traces_1m_v2, сгруппированная по минуте,ServiceName,StatusCodeиSpanName
Вторая materialized view содержит дополнительные ключи группировки и, следовательно, создаёт больше строк и сканирует больше данных.
Если визуализация запрашивает среднюю длительность по сервису во времени, обе materialized view технически допустимы. ClickStack выполняет запрос EXPLAIN ESTIMATE для каждого кандидата и сравнивает ожидаемое количество гранул, то есть:
Поскольку otel_traces_1m меньше и просматривает меньше гранул, он выбирается автоматически.
Оба materialized view по-прежнему работают быстрее, чем запросы напрямую к базовой таблице, но выбор наименьшего подходящего materialized view обеспечивает наилучшую производительность.
Оповещения
Запросы для оповещений автоматически используют materialized view, когда это совместимо. Применяется та же логика оптимизации, обеспечивая более быстрое срабатывание оповещений.
Дозаполнение materialized view
Как отмечалось ранее, incremental materialized views содержат только данные, вставленные после создания представления, и не дозаполняются автоматически. Такой подход делает представления лёгкими и недорогими в обслуживании, но также означает, что их нельзя использовать для запросов, которым нужны данные раньше минимальной временной метки представления.
В большинстве случаев это приемлемо. Типичные нагрузки ClickStack сосредоточены на недавних данных, например за последние 24 часа, поэтому вновь созданное представление становится полностью пригодным к использованию в течение суток после создания. Однако для запросов, охватывающих более длинные интервалы времени, представление может оставаться непригодным до тех пор, пока не пройдёт достаточно времени.
В таких случаях пользователи могут рассмотреть возможность дозаполнения (backfilling) materialized view историческими данными.
Дозаполнение может быть вычислительно дорогостоящим. В нормальном режиме работы materialized views заполняются инкрементально по мере поступления данных, равномерно распределяя вычислительную нагрузку во времени.
Дозаполнение сжимает этот объём работы в гораздо более короткий период, существенно увеличивая использование CPU и памяти в единицу времени.
В зависимости от объёма набора данных и окна хранения это может потребовать временного масштабирования кластера — вертикального либо горизонтального, в ClickHouse Cloud — чтобы завершить дозаполнение в разумные сроки.
Если дополнительные ресурсы не выделены, дозаполнение может негативно повлиять на продакшн-нагрузки, включая задержку запросов и пропускную способность при ингестии. Для очень больших наборов данных или длинных исторических периодов дозаполнение может оказаться непрактичным или вовсе нереализуемым.
В итоге дозаполнение часто не оправдывает затраты и операционные риски. К нему следует прибегать только в исключительных случаях, когда ускорение запросов по историческим данным критически важно. Если вы решаете выполнить дозаполнение, рекомендуется следовать контролируемому подходу, описанному ниже, чтобы сбалансировать производительность, стоимость и влияние на продакшн-среду.
Подходы к дозаполнению
Использование команды POPULATE не рекомендуется для дозаполнения materialized view, за исключением небольших наборов данных при приостановленном приёме данных. Этот оператор может пропускать строки, вставленные в исходную таблицу, если materialized view создаётся после завершения вычисления POPULATE hash. Кроме того, эта операция POPULATE выполняется по всем данным и подвержена прерываниям или ограничениям по памяти на больших наборах данных.
Предположим, вам нужно дозаполнить materialized view, соответствующий следующей агрегации, которая вычисляет поминутные метрики, сгруппированные по имени сервиса и коду статуса:
Как уже обсуждалось ранее, incremental materialized views не заполняются автоматически задним числом. Ниже описаны рекомендуемые процедуры безопасного заполнения исторических данных при сохранении инкрементального характера обработки новых данных.
Прямое дозаполнение с помощью INSERT INTO SELECT
Этот подход оптимально подходит для небольших наборов данных или относительно легковесных агрегирующих запросов, для которых полное дозаполнение можно выполнить за разумное время, не исчерпывая ресурсы кластера. Обычно он уместен, когда запрос дозаполнения выполняется несколько минут или, максимум, несколько часов, и когда временное увеличение нагрузки на CPU и I/O является приемлемым. Для более крупных наборов данных или более дорогих агрегаций вместо этого рассмотрите инкрементальные или блочно-ориентированные подходы к дозаполнению, описанные ниже.
Определите текущий охват представления
Перед попыткой какого-либо дозаполнения сначала нужно установить, какие данные уже содержит materialized view. Это делается с помощью запроса минимальной метки времени, присутствующей в целевой таблице:
Эта метка времени представляет собой самую раннюю точку, начиная с которой представление может обслуживать запросы. Любой запрос из ClickStack, запрашивающий данные ранее этой метки времени, будет обращаться к базовой таблице.
Решите, требуется ли дозаполнение
В большинстве развертываний ClickStack запросы сосредоточены на недавних данных, например за последние 24 часа. В таких случаях новые представления становятся полностью пригодными к использованию вскоре после создания, и дозаполнение не требуется.
Если метка времени, возвращенная на предыдущем шаге, достаточно старая для ваших сценариев использования, дозаполнение не требуется. Дозаполнение следует рассматривать только когда:
- запросы часто охватывают большие исторические диапазоны;
- представление критично для производительности на этих диапазонах;
- размер набора данных и стоимость агрегации делают дозаполнение осуществимым.
Заполните недостающие исторические данные
Если дозаполнение требуется, заполните целевую таблицу materialized view для меток времени, более ранних, чем текущий минимум, используя запрос, определенный в представлении, измененный так, чтобы считывать только данные старше зафиксированной выше метки времени. Поскольку целевая таблица использует AggregatingMergeTree, запрос дозаполнения должен вставлять состояния агрегации, а не конечные значения.
Этот запрос может обрабатывать большие объемы данных и быть ресурсоемким. Всегда проверяйте доступные ресурсы CPU, памяти и I/O перед запуском дозаполнения. Полезный прием — сначала выполнить запрос с FORMAT Null, чтобы оценить время выполнения и использование ресурсов.
Если ожидается, что сам запрос будет выполняться много часов, этот подход не рекомендуется.
Обратите внимание, что в следующем запросе добавляется предложение WHERE, чтобы ограничить агрегацию данными, более старыми, чем самая ранняя метка времени, присутствующая в представлении:
Инкрементальное заполнение с использованием таблицы Null
Для более крупных наборов данных или более ресурсоёмких агрегационных запросов прямое заполнение с использованием одного INSERT INTO SELECT может быть непрактичным или небезопасным. В таких случаях рекомендуется подход инкрементального заполнения. Этот метод ближе к тому, как обычно работают incremental materialized view, обрабатывая данные управляемыми блоками, а не агрегируя весь исторический набор данных сразу.
Такой подход целесообразен, когда:
- Иначе запрос заполнения будет выполняться в течение многих часов.
- Пиковое потребление памяти при полной агрегации слишком велико.
- Вам нужно точно контролировать использование CPU и памяти во время заполнения.
- Вам нужен более устойчивый процесс, который можно безопасно перезапустить в случае прерывания.
Ключевая идея — использовать таблицу Null в качестве буфера приёма. Хотя таблица Null не сохраняет данные, любые materialized view, прикреплённые к ней, всё равно будут выполняться, позволяя инкрементально вычислять состояния агрегации по мере прохождения данных.
Создайте таблицу Null для заполнения
Создайте лёгкую таблицу Null, которая содержит только столбцы, необходимые для агрегации materialized view. Это минимизирует использование ввода-вывода и памяти.
Прикрепите materialized view к таблице Null
Далее создайте materialized view на таблице Null, которая пишет в ту же таблицу агрегации, что и основная materialized view.
Эта materialized view будет выполняться инкрементально по мере вставки строк в таблицу Null, формируя состояния агрегации небольшими блоками.
Инкрементальное заполнение данных
Наконец, вставьте исторические данные в таблицу Null. Materialized view будет обрабатывать данные блок за блоком, отправляя состояния агрегации в целевую таблицу без сохранения сырых строк.
Поскольку данные обрабатываются инкрементально, использование памяти остаётся ограниченным и предсказуемым, что близко к обычному поведению ингестии.
Для дополнительной надёжности рассмотрите возможность направления materialized view для заполнения во временную целевую таблицу (например, otel_traces_1m_v2). После успешного завершения заполнения партиции можно переместить в основную целевую таблицу, например ALTER TABLE otel_traces_1m_v2 MOVE PARTITION '2026-01-02' TO otel_traces_1m. Это позволяет легко восстановиться, если заполнение будет прервано или завершится сбоем из-за ограничений ресурсов.
Для получения дополнительной информации по настройке этого процесса, включая повышение производительности вставки и сокращение и контроль использования ресурсов, см. "Заполнение исторических данных (Backfilling)".
Рекомендации
Следующие рекомендации обобщают передовые практики проектирования и эксплуатации materialized view в ClickStack. Соблюдение этих рекомендаций поможет обеспечить эффективное, предсказуемое и экономически выгодное использование materialized view.
Выбор и согласование детализации
Materialized views используются только тогда, когда детализация визуализации или алерта является точным кратным детализации представления. То, как определяется эта детализация, зависит от типа графика:
-
Временные графики (линейные или столбчатые графики со временем по оси X): Явная детализация графика должна быть кратна детализации materialized view. Например, график с шагом 10 минут может использовать materialized views с детализацией 10, 5, 2 или 1 минута, но не 20 минут и не 3 минуты.
-
Невременные графики (метрика-число, таблица или сводные графики): Эффективная детализация вычисляется как
(time range / 80), с округлением вверх до ближайшей детализации, поддерживаемой HyperDX. Эта вычисленная детализация также должна быть кратна детализации materialized view.
Вследствие этих правил:
- Не создавайте materialized views с детализацией 10 минут. ClickStack поддерживает 15-минутную детализацию для графиков и алертов, но не 10-минутную. Поэтому materialized view с детализацией 10 минут будет несовместим с типичными 15-минутными визуализациями и алертами.
- Отдавайте предпочтение детализации 1 минута или 1 час, которые хорошо сочетаются с большинством конфигураций графиков и алертов.
Более грубая детализация (например, 1 час) даёт меньшие по размеру представления и снижает накладные расходы на хранение, в то время как более мелкая детализация (например, 1 минута) обеспечивает большую гибкость для детализированного анализа. Выбирайте наименьшую детализацию, которая поддерживает ваши критически важные сценарии.
Ограничивайте и объединяйте materialized views
Каждая materialized view добавляет накладные расходы при вставке и увеличивает нагрузку на создание и слияние частей (parts and merges). Рекомендуются следующие практики:
- Не более 20 materialized views на один источник.
- Около 10 materialized views обычно оптимально.
- Объединяйте несколько визуализаций в одну materialized view, если у них есть общие измерения.
По возможности вычисляйте несколько метрик и поддерживайте несколько графиков из одной materialized view.
Тщательно выбирайте размерности
Включайте только те размерности, которые регулярно используются для группировки или фильтрации:
- Каждый дополнительный столбец группировки увеличивает размер materialized view.
- Уравновешивайте гибкость запросов и затраты на хранение и вставку данных.
- Фильтры по столбцам, отсутствующим во view, заставят ClickStack обращаться к исходной таблице.
Распространённым и почти всегда полезным базовым вариантом является materialized view, сгруппированное по имени сервиса с метрикой count, что обеспечивает быстрые гистограммы и обзоры на уровне сервисов в поиске и на дашбордах.
Соглашения об именовании столбцов агрегации
Столбцы агрегации в materialized view должны следовать строгому соглашению об именовании, чтобы обеспечить их автоматическое определение:
- Шаблон:
<aggFn>__<sourceColumn> - Примеры:
avg__Durationmax__Durationcount__для подсчёта строк
ClickStack полагается на это соглашение, чтобы корректно сопоставлять запросы со столбцами в materialized view.
Квантили и выбор скетч-функции
Разные функции квантилей обладают разными характеристиками производительности и хранения:
quantilesсоздаёт более крупные скетчи на диске, но дешевле в вычислении во время вставки.quantileTDigestдороже в вычислении во время вставки, но создаёт меньшие скетчи, что часто приводит к более быстрым запросам к представлениям.
Вы можете указать размер скетча при вставке для обеих функций (например, quantile(0.5)). Получившийся скетч по‑прежнему можно использовать для запросов других значений квантилей, например quantile(0.95). Рекомендуется поэкспериментировать, чтобы найти оптимальный баланс для вашей нагрузки.
Постоянно проверяйте эффективность
Всегда удостоверяйтесь, что materialized view действительно дают реальный эффект:
- Подтвердите их использование по индикаторам ускорения в интерфейсе.
- Сравните производительность запросов до и после включения materialized view.
- Отслеживайте использование ресурсов и поведение слияний.
К materialized view следует относиться как к средству оптимизации производительности, которое требует периодического пересмотра и настройки по мере изменения шаблонов запросов.
Расширенные конфигурации
Для более сложных рабочих нагрузок можно использовать несколько materialized view для поддержки разных паттернов доступа. Примеры включают:
- Высокодетализированные данные за недавний период с менее детализированными представлениями для исторических данных
- Представления на уровне сервисов для обзоров и представления на уровне конечных точек (endpoint) для глубокой диагностики
Эти паттерны могут значительно повысить производительность при выборочном применении, но их следует внедрять только после проверки более простых конфигураций.
Следование этим рекомендациям поможет обеспечить, что materialized view останутся эффективными, удобными в сопровождении и согласованными с моделью выполнения ClickStack.
Ограничения
Распространённые причины несовместимости
materialized view не будет использоваться, если выполняется любое из следующих условий:
-
Диапазон времени запроса
Начало временного диапазона запроса предшествует минимальной метке времени materialized view. Поскольку представления не заполняются задним числом автоматически, они могут обслуживать только запросы для тех временных диапазонов, которые полностью покрывают. -
Несоответствие гранулярности
Эффективная гранулярность визуализации должна быть точным кратным гранулярности materialized view. В частности:- Для временных графиков (линейных или столбчатых графиков с временем по оси X) выбранная гранулярность графика должна быть кратна гранулярности представления. Например, 10-минутный график может использовать materialized view с гранулярностью 10, 5, 2 или 1 минута, но не 20-минутные или 3-минутные представления.
- Для невременных графиков (числовые или табличные графики) эффективная гранулярность вычисляется как
(time range / 80), округлённая вверх до ближайшей поддерживаемой HyperDX гранулярности и также должна быть кратна гранулярности представления.
-
Неподдерживаемые агрегирующие функции
Запрос запрашивает агрегацию, которая отсутствует в materialized view. Можно использовать только те агрегации, которые явно вычислены и сохранены в представлении. -
Пользовательские выражения для подсчёта
Запросы, использующие выражения видаcount(if(...))или другие условные подсчёты, не могут быть получены из стандартных состояний агрегации и, следовательно, не могут использовать materialized view.
Ограничения проектирования и эксплуатации
-
Отсутствие автоматического бэкфиллинга Incremental materialized views содержат только данные, вставленные после их создания. Для ускорения работы с историческими данными требуется явный бэкфиллинг, который может быть дорогим или непрактичным для больших наборов данных.
-
компромиссы по гранулярности Представления с очень высокой гранулярностью увеличивают размер хранилища и накладные расходы при вставке, тогда как крупная гранулярность снижает гибкость. Гранулярность необходимо тщательно подбирать в соответствии с ожидаемыми шаблонами запросов.
-
взрыв размерности Добавление большого количества группирующих измерений значительно увеличивает размер представления и может снизить его эффективность. Представления должны включать только часто используемые столбцы для группировки и фильтрации.
-
ограниченная масштабируемость по числу представлений Каждый materialized view добавляет накладные расходы при вставке и увеличивает нагрузку на слияния. Создание слишком большого числа представлений может негативно повлиять на ингестию и фоновые слияния.
Понимание этих ограничений помогает применять materialized views там, где они дают реальную пользу, и избегать конфигураций, которые незаметно приводят к более медленным запросам к исходным таблицам.
Устранение неполадок
materialized view не используется
Проверка 1: диапазон дат
- Откройте модальное окно оптимизации и проверьте, не указано ли там "Date range not supported."
- Убедитесь, что диапазон дат запроса начинается позже минимальной даты materialized view.
- Уберите ограничение по минимальной дате, если materialized view содержит все исторические данные.
Проверка 2: гранулярность
- Проверьте, что гранулярность графика является кратной гранулярности MV.
- Попробуйте установить для графика значение "Auto" или вручную выбрать совместимую гранулярность.
Проверка 3: агрегации
- Проверьте, использует ли график агрегации, определённые в MV.
- Просмотрите раздел "Available aggregated columns" в модальном окне оптимизации.
Проверка 4: измерения
- Убедитесь, что столбцы GROUP BY входят в измерения MV.
- Проверьте раздел "Available group/filter columns" в модальном окне оптимизации.
Медленные запросы к materialized view
Проблема 1: слишком мелкая гранулярность materialized view
- В materialized view слишком много строк из-за низкой гранулярности (например, 1 секунда).
- Решение: создайте materialized view с более крупной гранулярностью (например, 1 минута или 1 час).
Проблема 2: слишком много измерений
- У materialized view высокая кардинальность из-за большого числа столбцов измерений.
- Решение: уменьшите число столбцов измерений, оставив только наиболее часто используемые.
Проблема 3: несколько materialized view с большим числом строк
- Система выполняет
EXPLAINдля каждой materialized view. - Решение: удалите materialized view, которые редко используются или всегда пропускаются.
Ошибки конфигурации
Ошибка: «At least one aggregated column is required»
- Добавьте по крайней мере один агрегированный столбец в конфигурацию MV.
Ошибка: «Source column is required for non-count aggregations»
- Укажите, какой столбец агрегировать (только count может не указывать исходный столбец).
Ошибка: «Invalid granularity format»
- Используйте одну из предустановленных степеней детализации из выпадающего списка.
- Формат должен быть корректным SQL-интервалом (например,
1 hour, а не1 h).
