предисловие
В предыдущем разделе мы представили, как получать журналы клиента и хранилище данных для записей и обновлений ClickHouse. Говоря о записи, мы упомянули пакетную запись, которая полезна для ClickHouse при обработке новых данных. Однако, если мы хотим обеспечить более высокую скорость запросов, какую структуру данных мы должны использовать для организации записи данных? В этом разделе давайте познакомимся с тем, как организовать данные в ClickHouse для эффективного выполнения запросов.
1. Раздел данных ClickHouse
Разделение данных заключается в размещении данных в разных каталогах в соответствии с одним или несколькими полями.Во многих базах данных OLAP существует схема разделения данных, но многие другие базы данных OLAP не имеют функции автоматического объединения небольших файлов в разделе. ClickHouse будет периодически объединять небольшие файлы в раздел для повышения производительности запросов. Наиболее часто используется разделение по дням. В таблицах движка ClickHouse серии MergeTree поля раздела указываются через раздел при создании таблицы, например:
CREATE TABLE test (
event String,
user_id Int64,
event_time String,
dt String
) ENGINE = MergeTree()
partition by dt
order by event
Где dt — поле раздела. С полем раздела, когда мы запрашиваем данные, мы можем использовать условие where для фильтрации через поле раздела, уменьшая объем сканирования данных и повышая эффективность запроса. Например, если мы хотим запросить только объем данных с 1 по 30 сентября 2021 года, мы можем выполнить следующий sql, чтобы получить:
select count(1) from test where dt between '20210901' and '20210930'
На следующем рисунке представлена принципиальная схема перегородки
Например, 20210201 представляет собой большой раздел, который является полевым полем, которое мы определены. В большом разделе есть много маленьких файлов. Каждый файл может быть файлом, сгенерированным одним вставкой, например, 20210201_2_0, 20210201_2_2_0 и т. Д.
Хотя секционирование может уменьшить диапазон сканирования данных во время запроса, важно помнить, что секции нельзя делить слишком мелко, например, секционирование выполняется на уровне минут, поскольку одна секция движка таблиц MergeTree соответствует пакету файлов. Если файлов слишком много, то при запросе будет просканировано большое количество мелких файлов, и будет сгенерировано большое количество файловых адресаций, что несомненно увеличит время запроса. Кроме того, ClickHouse будет регулярно объединять небольшие файлы в каждом разделе, слишком много разделов может привести к тому, что ClickHouse будет объединять небольшие файлы быстрее, чем скорость записи данных в сгенерированные небольшие файлы. Поэтому степень детализации раздела не может быть слишком мелкой.
Во-вторых, индекс первого уровня движка ClickHouse MergeTree.
1. Пример использования первичного индекса
ClickHouse提供了一级索引,查询时使用一级索引,能大幅度提高查询性能,一级索引在创建表时通过order by关键字声明,也可通过primary key声明。如果不声明primary key关键字,那么默认情况下order by关键字声明的字段就是一级索引。 Пример выглядит следующим образом:
CREATE TABLE heaven_eye_analyse.event_production (
event String,
user_id Int64,
$lib String,
dt String
) ENGINE = MergeTree()
partition by dt
order by event
Событие является индексом первого уровня.
Давайте сравним и старение при использовании общих индексных полей. Общий объем сравнения данных составляет 50 миллионов. Сначала посмотрите на обычные поля старения с помощью запросов
Обычные полевые запросы с помощью $lib составляют данные за 30 дней, что занимает 15 секунд. Затем посмотрите на использование отнимающего много времени индекса запросов.
Видно, что трудоемкость составляет всего 430 мс, а скорость совершенно раздавлена по сравнению с использованием обычных полевых запросов.
2. Принцип первичной индексации
Далее мы вводим принцип работы индекса первого уровня ClickHouse. Ниже приведена схема индекса первого уровня.
Для каждого столбца в таблице MergeTree есть два файла: один файл .bin, а другой — файл .mrk. В дополнение к основному индексу имеется файл primary.idx.
.bin-файл
Файлы .bin используются для хранения данных.
Поскольку данные в одном и том же столбце имеют высокую вероятность сходства, обычно это сжатое хранилище данных, может сэкономить место на диске, но сжатие не является сжатием ClickHosue для всего файла .bin, а данные разделены файлом .bin на несколько разделы каждой части сжимаются вместе, называемые блоком сжатия, преимущества этого заключаются в следующем: например, весь файл .bin содержит 100 миллионов данных, если сжимается весь файл, предполагается, что только чтение которых десять тысяч данных, вам нужно распаковать весь файл, тем самым потратив много времени. Напротив, если только хранится распаковка блока данных, где миллион, то эффективность значительно улучшится.
Кроме того, в каждом сжатом блоке есть одни метаданные, метаданные занимают 9 байтов, 1 байт представляет тип алгоритма сжатия, 4 байта представляет размер данных до сжатия, а 4 байта представляют размер сжатых данных.
.mrk-файл
Файл .mrk используется для описания начального положения каждого блока данных в файле .bin, соответствующего этому столбцу (интервал из каждых 8192 фрагментов данных по умолчанию), и положения данных в блоке данных (после распаковки).
файл primary.idx
Первичный индекс соответствует файлу primary.idx. Таблица ClickHouse MergeTree формирует индексную метку для каждого определенного количества данных (по умолчанию 8192).Для 100 миллионов фрагментов данных для индексации можно использовать 12208 строк индексных меток.С этой точки зрения пространство, занимаемое индексными метками, будет быть очень маленьким, поэтому индексный файл может находиться в памяти для увеличения скорости доступа.
Synergistic primary.idx, файл тегов, файл данных
Из приведенной выше схемы индекса первого уровня видно, что каждая строка маркеров индекса в файле primary.idx и каждый маркер в файле .mrk соответствующего столбца индекса имеют отношение один к одному, и маркеры и сжатые блоки соответствуют индексу первого уровня.Размер поля до сжатия, разделенный на один-к-одному, один-ко-многим и многие-к-одному. Если вы хотите запросить данные в определенном диапазоне на основе поля индекса первого уровня, вы можете пересечь условие запроса с индексом первого уровня, чтобы найти метку, соответствующую интервалу, в котором находятся данные. Например, если вы хотите запросить данные между событиями между 5000 и 6000, по индексу первого уровня обнаруживается, что индекс 4553 имеет пересечение с условиями запроса, а затем по индексу 4553 маркер 1 найден, и маркер 1 указывает на сжатый блок 1. В это время сначала распаковать сжатый блок 1. Поскольку позиция P2 метки 1 равна 0, начните с первого элемента после распаковки и найдите данные, которые соответствуют условия (событие между 5000 и 6000).
Суммировать
В этом разделе мы в основном представим два способа, с помощью которых ClickHouse повышает эффективность запросов, а именно секционирование и хранение индексов первого уровня с помощью механизма таблиц ClickHouse MergeTree. Сочетание двух методов позволяет нам значительно повысить производительность при выполнении запросов.
Следующие основные моменты:
При использовании разделов помните, что разделы не могут быть разделены слишком мелко.
При использовании индекса первого уровня в качестве индекса первого уровня следует выбрать условие, которое может часто встречаться во время запроса.
Узнав, как эффективно организовать хранение данных, в следующем разделе мы познакомим вас с тем, как проводить анализ бизнес-данных на основе ClickHouse, например анализ типичной воронкообразной модели, анализ удержания бизнеса и т. д.