Партиции
PARTITION BY. Это условие может содержать SQL-выражение для любого столбца или набора столбцов, результат которого определяет, в какую партицию будет направлена строка.
Части данных логически связаны (через общий префикс имени папки) с каждой партицией на диске и могут запрашиваться изолированно. В примере ниже схема otel_logs по умолчанию использует партиционирование по дням с выражением toDate(Timestamp). По мере вставки строк в ClickHouse это выражение вычисляется для каждой строки, и данные направляются в соответствующую партицию, если она уже существует (если строка для этого дня первая, партиция будет создана).
otel_logs разбита на партиции по дням. Если она заполнена структурированным набором журнальных данных, она будет содержать данные за несколько дней:
otel_logs_archive, которую мы используем для хранения более старых данных. Данные можно эффективно перемещать в эту таблицу по партициям (это лишь изменение метаданных).
INSERT INTO SELECT и перезапись данных в новую целевую таблицу.
Перемещение партицийДля перемещения партиций между таблицами необходимо соблюдение нескольких условий; в частности, таблицы должны иметь одинаковые структуру, ключ партиционирования, первичный ключ и индексы/проекции. Подробные сведения о том, как указывать партиции в
ALTER DDL, можно найти здесь.Эта возможность задействуется механизмом TTL при использовании настройки
ttl_only_drop_parts=1. Подробнее см. в разделе Управление данными с помощью TTL.Применение
- Многоуровневые архитектуры - перемещение данных между уровнями хранения (см. Уровни хранения), что позволяет строить архитектуру «горячего» и «холодного» хранения.
- Эффективное удаление - когда данные достигают заданного TTL (см. Управление данными с помощью TTL)
Производительность запросов
Управление данными с помощью TTL (Time-to-live)
TTL на уровне таблицы
ttl, например.
h и следить за тем, чтобы значение соответствовало периоду партиционирования. Например, если таблица партиционируется по дням, убедитесь, что значение кратно количеству дней, например 24h, 48h, 72h. Это автоматически обеспечит добавление в таблицу предложения TTL, например при ttl: 96h.
TTL по расписаниюTTL применяется не сразу, а по расписанию, как указано выше. Настройка таблицы MergeTree
merge_with_ttl_timeout задает минимальную задержку в секундах перед повторным выполнением слияния с delete TTL. Значение по умолчанию — 14400 секунд (4 часа). Но это лишь минимальная задержка: до запуска TTL-слияния может пройти больше времени. Если значение слишком мало, будет выполняться много внеплановых слияний, которые могут потреблять значительные ресурсы. Принудительно применить TTL можно командой ALTER TABLE my_table MATERIALIZE TTL.ttl_only_drop_parts=1 ** (она применяется в схеме по умолчанию). Когда эта настройка включена, ClickHouse удаляет часть целиком, если в ней истекли все строки. Удаление частей целиком вместо частичной очистки строк с истекшим TTL (которая выполняется с помощью ресурсоемких мутаций при ttl_only_drop_parts=0) позволяет использовать меньшие значения merge_with_ttl_timeout и снижает влияние на производительность системы. Если данные партиционированы по той же единице, по которой выполняется истечение TTL, например по дням, части естественным образом будут содержать данные только из заданного интервала. Это гарантирует, что ttl_only_drop_parts=1 можно будет применять эффективно.
TTL на уровне столбца
Body на случай, если будут добавлены новые динамические метаданные, которые не были извлечены во время вставки, например новая метка Kubernetes. Через некоторое время, например через 1 месяц, может стать очевидно, что эти дополнительные метаданные не приносят пользы, — и тогда хранение столбца Body теряет смысл.
Ниже показано, как удалить столбец Body через 30 дней.
Чтобы задать TTL на уровне столбца, пользователям нужно определить собственную схему. Это нельзя указать в OTel collector.
Повторное сжатие данных
ZSTD(1), вы можете поэкспериментировать с другими алгоритмами сжатия или более высокими уровнями сжатия, например ZSTD(3). Помимо возможности указать это при создании схемы, сжатие можно настроить так, чтобы оно менялось по истечении определённого времени. Это может быть уместно, если кодек или алгоритм сжатия обеспечивает лучшее сжатие, но снижает производительность запросов. Такой компромисс может быть приемлем для старых данных, к которым обращаются реже, но не для свежих данных, которые чаще используются при расследованиях.
Пример показан ниже: вместо удаления данных через 4 дня мы начинаем сжимать их с помощью ZSTD(3).
Оцените производительностьМы рекомендуем всегда оценивать, как разные уровни сжатия и алгоритмы влияют на производительность вставки и запросов. Например, дельта-кодеки могут быть полезны для сжатия временных меток. Однако если они входят в состав первичного ключа, производительность фильтрации может снизиться.
Уровни хранения
Не относится к ClickHouse CloudClickHouse Cloud использует одну копию данных, размещённую в S3, с кэшами узлов на SSD. Поэтому уровни хранения в ClickHouse Cloud не требуются.
ALTER TABLE MOVE PARTITION, перемещением данных между томами также можно управлять с помощью TTL. Полный пример можно найти здесь.
Управление изменениями схемы
Использование значений по умолчанию
DEFAULT. Указанное значение по умолчанию будет использоваться, если оно не задано при INSERT.
Изменения в схему можно внести до изменения логики преобразования в materialized view или конфигурации OTel collector, из-за которых начнётся отправка новых столбцов.
После изменения схемы можно перенастроить OTel collectors. Если пользователи применяют рекомендуемый процесс, описанный в “Извлечение структуры с помощью SQL”, при котором OTel collectors отправляют данные в движок таблицы Null, а materialized view отвечает за извлечение целевой схемы и отправку результатов в целевую таблицу для хранения, представление можно изменить с помощью синтаксиса ALTER TABLE ... MODIFY QUERY. Предположим, у нас есть приведённая ниже целевая таблица и соответствующее ей materialized view (аналогичное тому, что используется в “Извлечение структуры с помощью SQL”) для извлечения целевой схемы из структурированных журналов OTel:
Size из LogAttributes. Мы можем добавить его в схему с помощью ALTER TABLE, указав значение по умолчанию:
size в LogAttributes (если его нет, будет 0). Это означает, что запросы, обращающиеся к этому столбцу для строк, в которые это значение не было вставлено, должны обращаться к Map и, следовательно, будут выполняться медленнее. Мы также могли бы легко указать здесь константу, например 0, снизив стоимость последующих запросов к строкам, в которых это значение отсутствует. Запрос к этой таблице показывает, что значение заполняется из Map, как и ожидалось:
ALTER TABLE, как показано ниже:
Size будет заполняться при вставке.
Создание новых таблиц
ALTER TABLE MODIFY QUERY. При таком подходе можно версионировать таблицы, например otel_logs_v3.
При таком подходе пользователям придётся выполнять запросы к нескольким таблицам. Чтобы выполнять запросы сразу к нескольким таблицам, можно использовать функцию merge, которая поддерживает шаблоны с подстановочными знаками в имени таблицы. Ниже это показано на примере запроса к версиям v2 и v3 таблицы otel_logs:
merge и предоставить конечным пользователям таблицу, объединяющую несколько таблиц, можно использовать движок таблицы Merge. Ниже мы покажем, как это сделать:
EXCHANGE. Например, чтобы добавить таблицу v4, можно создать новую таблицу и атомарно поменять её местами с предыдущей версией.