Изучение архитектуры разделения хранения и вычислений ClickHouse

Архитектура

задний план

Как движок OLAP с открытым исходным кодом, ClickHouse широко используется в экосистеме больших данных благодаря своей превосходной производительности. В отличие от экологических компонентов Hadoop, которые обычно полагаются на HDFS в качестве базового хранилища данных, ClickHouse использует локальные диски для самостоятельного управления данными, а SSD официально рекомендуется в качестве носителя для повышения производительности. Однако из-за ограниченной емкости локальных дисков и цены на SSD-диски пользователям сложно найти хороший баланс между емкостью, стоимостью и производительностью. Клиент JuiceFS недавно столкнулся с такой проблемой, надеясь перенести «горячие» и «холодные» данные в ClickHouse с SSD-дисков на более емкие и недорогие носители данных, чтобы лучше поддерживать потребности бизнес-запросов в данных в течение более длительных периодов времени.

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

Введение в формат хранения MergeTree

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

$ ls -l /var/lib/clickhouse/data/<database>/<table>
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202102_1_3_0
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202102_4_6_1
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202103_1_1_0
drwxr-xr-x  2 test  test    64B Mar  8 13:46 202103_4_4_0

от202102_1_3_0Например,202102это имя раздела,1это наименьший номер блока данных,3самый большой номер блока данных,0это глубина MergeTree. Вы можете видеть, что раздел 202102 имеет более одного каталога, потому что ClickHouse создает новый каталог каждый раз, когда он записывает, и он не будет изменен (неизменен) после записи. Каждый каталог называется "частью". Когда количество частей постепенно увеличивается, ClickHouse будет объединять несколько частей в фоновом режиме. Общая рекомендация - не хранить слишком много частей, иначе это повлияет на производительность запроса.

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

$ ls -l /var/lib/clickhouse/data/<database>/<table>/202102_1_3_0
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnA.bin
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnA.mrk
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnB.bin
-rw-r--r--  1 test  test     ?? Mar  8 14:06 ColumnB.mrk
-rw-r--r--  1 test  test     ?? Mar  8 14:06 checksums.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 columns.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 count.txt
-rw-r--r--  1 test  test     ?? Mar  8 14:06 minmax_ColumnC.idx
-rw-r--r--  1 test  test     ?? Mar  8 14:06 partition.dat
-rw-r--r--  1 test  test     ?? Mar  8 14:06 primary.idx

Среди наиболее важных документов:

primary.idx: Этот файл содержит информацию о первичном ключе, но не первичный ключ всех строк текущей части.По умолчанию он будет храниться в интервале 8192, то есть первичный ключ будет храниться каждые 8192 строки.ColumnA.bin: это данные определенного столбца после сжатия, ColumnA — это просто имя этого столбца, фактическая ситуация будет реальным именем столбца. Сжатие выполняется в блоках как наименьших единицах, а размер каждого блока варьируется от 64 КБ до 1 МБ.ColumnA.mrk: этот файл сохраняет смещение каждого блока после сжатия и до сжатия в соответствующем файле ColumnA.bin.partition.dat: Этот файл содержит идентификатор раздела после вычисления выражения раздела.minmax_ColumnC.idx: Этот файл содержит минимальные и максимальные значения исходных данных, соответствующие полям раздела.

Схема разделения хранения и вычислений на основе JuiceFS

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

image.png

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

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

image.png

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

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

<storage_configuration>
    <disks>
        <jfs>
            <path>/jfs</path>
        </jfs>
    </disks>
</storage_configuration>

выше/jfsКаталог — это путь, по которому смонтирована файловая система JuiceFS. После добавления приведенной выше конфигурации в файл конфигурации ClickHouse и успешного монтирования файловой системы JuiceFS вы можете переместить раздел в JuiceFS с помощью команды MOVE PARTITION, например:

ALTER TABLE test MOVE PARTITION 'xxx' TO DISK 'jfs';

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

<storage_configuration>
    <disks>
        <jfs>
            <path>/jfs</path>
        </jfs>
    </disks>
    <policies>
        <hot_and_cold>
            <volumes>
                <hot>
                    <disk>default</disk>
                    <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                </hot>
                <cold>
                    <disk>jfs</disk>
                </cold>
            </volumes>
            <move_factor>0.1</move_factor>
        </hot_and_cold>
    </policies>
</storage_configuration>

В приведенном выше файле конфигурации есть файл с именемhot_and_coldПолитика хранения , определяющая два тома с именамиhotОбъем — это SSD-диск по умолчанию с именемcoldГромкость — это предыдущий шагdisksДиск JuiceFS, как определено в . Порядок этих томов в конфигурационном файле важен, данные сначала сохраняются в первом томе, а затемmax_data_part_size_bytesЭта конфигурация означает, что когда часть данных превышает указанный размер (в примере 1 ГБ), она автоматически перемещается с текущего тома на следующий том, то есть данные перемещаются с SSD-диска в JuiceFS. Последний move_factorКонфигурация означает, что перемещение данных в JuiceFS также будет инициировано, когда емкость диска SSD превысит 90%.

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

CREATE TABLE test (
  ...
) ENGINE = MergeTree
...
SETTINGS storage_policy = 'hot_and_cold';

При выполнении условий для перемещения данных ClickHouse запустит фоновый поток для выполнения операции перемещения данных.По умолчанию одновременно будет работать 8 потоков.Это количество потоков можно пропустить черезbackground_move_pool_sizeКорректировка конфигурации.

Помимо настройки политик хранения, вы также можете передатьTTLПереместите данные за определенный период времени в JuiceFS, например:

CREATE TABLE test (
  d DateTime,
  ...
) ENGINE = MergeTree
...
TTL d + INTERVAL 1 DAY TO DISK 'jfs'
SETTINGS storage_policy = 'hot_and_cold';

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

Написать тест производительности

После принятия схемы разделения «горячих» и «холодных» данных данные не будут напрямую записываться в JuiceFS, а сначала записываются на SSD-диск, а затем асинхронно переносятся в JuiceFS через фоновый поток. Однако мы хотим напрямую оценить разницу в производительности разных носителей при записи данных, поэтому не настраиваем стратегию хранения по разделению горячих и холодных данных при тестировании производительности записи, а позволяем ClickHouse напрямую писать на разные носители.

Конкретный метод тестирования состоит в том, чтобы использовать таблицу ClickHouse в реальном бизнесе в качестве источника данных, а затем использовать оператор INSERT INTO для вставки десятков миллионов строк данных в пакетах и ​​сравнивать пропускную способность прямой записи на SSD-диск, JuiceFS и хранения объектов. Окончательные результаты испытаний следующие:

image.png

**Используя SSD-диск в качестве эталона, мы видим, что производительность записи JuiceFS примерно на 30% ниже, чем у SSD-диска, но при этом производительность выше в 11 раз по сравнению с объектным хранилищем. **В тесте JuiceFS здесь включена опция обратной записи, потому что ClickHouse будет генерировать большое количество маленьких файлов (уровень KiB) для каждой части при записи.Маленькие файлы также оказывают определенное влияние на производительность запросов.

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

Тест производительности запроса

Тест производительности запросов использует данные в реальном бизнесе и выбирает несколько типичных сценариев запросов для тестирования. Где q1-q4 — это запросы, которые сканируют всю таблицу, а q5-q7 — это запросы, которые обращаются к индексу первичного ключа. Результаты теста следующие:

image.png

image.png

**Видно, что производительность запросов JuiceFS и SSD-дисков в основном одинакова, со средней разницей около 6%, но производительность объектного хранилища от 1,4 до 30 раз ниже, чем у SSD-дисков. ** Благодаря высокопроизводительной работе с метаданными и функции локального кэширования JuiceFS горячие данные, необходимые для запроса запроса, могут автоматически кэшироваться локально на узле ClickHouse, что значительно повышает производительность запросов ClickHouse. Следует отметить, что доступ к объектному хранилищу в приведенном выше тесте осуществляется через тип диска ClickHouse S3, таким образом, в объектном хранилище хранятся только данные, а метаданные остаются на локальном диске. Если объектное хранилище монтируется локально аналогично S3FS, производительность будет снижаться еще больше.

После выполнения базового теста производительности запроса следующим шагом является тестирование производительности запроса в схеме разделения «горячих» и «холодных» данных. В отличие от предыдущего теста, когда используется схема разделения горячих и холодных данных, не все данные находятся в JuiceFS, и данные сначала будут записаны на диск SSD.

Сначала выберите фиксированный диапазон времени запроса, чтобы оценить влияние кэширования JuiceFS на производительность.Результаты теста следующие:

image.png

Как и в случае с запросом с фиксированным диапазоном времени, создание кеша приводит к повышению производительности примерно на 78% по сравнению со вторым запросом. Разница в том, что четвертый запрос включает в себя запрос только что записанных или объединенных данных, а JuiceFS в настоящее время не кэширует большие файлы при записи, что окажет определенное влияние на производительность запроса.После этого будут предоставлены параметры, позволяющие разрешить запись в кэш. повысить производительность запросов для новых данных.

Суммировать

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

Перспектива

В текущей среде, где все больше и больше внимания уделяется облачным технологиям, разделение хранения и вычислений стало общей тенденцией. Дорожная карта ClickHouse на 2021 год четко определила разделение хранения и вычислений в качестве основной цели.Хотя ClickHouse в настоящее время поддерживает хранение данных на S3, реализация все еще относительно грубая. В будущем JuiceFS также будет тесно сотрудничать с сообществом ClickHouse, чтобы исследовать направление разделения хранилища и вычислений, чтобы ClickHouse мог лучше идентифицировать и поддерживать совместно используемое хранилище, и ему не нужно было выполнять какое-либо копирование данных при реализации масштабирования кластера.

разное:

Elasticsearch экономит 60 % затрат на хранение